@firmachain/firma-js 0.3.8 → 0.4.0-beta2

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 (131) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +1 -0
  3. package/dist/sdk/FirmaAuthzService.js +20 -15
  4. package/dist/sdk/FirmaBankService.d.ts +1 -1
  5. package/dist/sdk/FirmaBankService.js +5 -4
  6. package/dist/sdk/FirmaConfig.js +4 -4
  7. package/dist/sdk/FirmaContractService.js +10 -8
  8. package/dist/sdk/FirmaDistributionService.js +20 -15
  9. package/dist/sdk/FirmaFeeGrantService.d.ts +0 -1
  10. package/dist/sdk/FirmaFeeGrantService.js +12 -14
  11. package/dist/sdk/FirmaGovService.d.ts +14 -0
  12. package/dist/sdk/FirmaGovService.js +58 -37
  13. package/dist/sdk/FirmaIbcService.js +4 -3
  14. package/dist/sdk/FirmaNftService.d.ts +3 -3
  15. package/dist/sdk/FirmaNftService.js +13 -10
  16. package/dist/sdk/FirmaStakingService.d.ts +4 -0
  17. package/dist/sdk/FirmaStakingService.js +58 -33
  18. package/dist/sdk/FirmaTokenService.js +17 -14
  19. package/dist/sdk/FirmaUtil.js +1 -1
  20. package/dist/sdk/FirmaWalletService.d.ts +1 -1
  21. package/dist/sdk/FirmaWalletService.js +11 -23
  22. package/dist/sdk/firmachain/authz/AuthzTxClient.js +2 -0
  23. package/dist/sdk/firmachain/bank/BankTxClient.js +1 -1
  24. package/dist/sdk/firmachain/common/CommonTxClient.js +3 -1
  25. package/dist/sdk/firmachain/common/FirmaLedger.d.ts +49 -0
  26. package/dist/sdk/firmachain/common/FirmaLedger.js +301 -0
  27. package/dist/sdk/firmachain/common/ITxClient.d.ts +1 -1
  28. package/dist/sdk/firmachain/common/ITxClient.js +6 -4
  29. package/dist/sdk/firmachain/common/LedgerWallet.d.ts +5 -13
  30. package/dist/sdk/firmachain/common/LedgerWallet.js +1266 -124
  31. package/dist/sdk/firmachain/common/SigningProtobufStargateClient.js +3 -4
  32. package/dist/sdk/firmachain/common/SigningStargateClient.d.ts +2 -3
  33. package/dist/sdk/firmachain/common/SigningStargateClient.js +7 -10
  34. package/dist/sdk/firmachain/common/index.d.ts +1 -0
  35. package/dist/sdk/firmachain/common/index.js +1 -0
  36. package/dist/sdk/firmachain/common/signing.d.ts +4 -10
  37. package/dist/sdk/firmachain/common/signing.js +13 -60
  38. package/dist/sdk/firmachain/contract/ContractTxClient.js +1 -1
  39. package/dist/sdk/firmachain/contract/ContractTxTypes.js +54 -8
  40. package/dist/sdk/firmachain/distribution/DistributionTxClient.js +1 -1
  41. package/dist/sdk/firmachain/feegrant/FeeGrantTxClient.js +3 -1
  42. package/dist/sdk/firmachain/feegrant/FeeGrantTxTypes.d.ts +1 -2
  43. package/dist/sdk/firmachain/google/protobuf/any.js +0 -12
  44. package/dist/sdk/firmachain/gov/GovTxClient.js +3 -0
  45. package/dist/sdk/firmachain/nft/NftTxClient.js +1 -1
  46. package/dist/sdk/firmachain/staking/StakingQueryClient.d.ts +15 -0
  47. package/dist/sdk/firmachain/staking/StakingQueryClient.js +109 -0
  48. package/dist/sdk/firmachain/token/TokenTxClient.js +1 -1
  49. package/package.json +18 -9
  50. package/dist/test/00.wallet.test.d.ts +0 -1
  51. package/dist/test/00.wallet.test.js +0 -96
  52. package/dist/test/01.contract_tx.test.d.ts +0 -1
  53. package/dist/test/01.contract_tx.test.js +0 -157
  54. package/dist/test/02.contract_query.test.d.ts +0 -1
  55. package/dist/test/02.contract_query.test.js +0 -245
  56. package/dist/test/03.contract_scenario.test.d.ts +0 -1
  57. package/dist/test/03.contract_scenario.test.js +0 -406
  58. package/dist/test/04.bank_tx.test.d.ts +0 -1
  59. package/dist/test/04.bank_tx.test.js +0 -126
  60. package/dist/test/05.bank_query.test.d.ts +0 -1
  61. package/dist/test/05.bank_query.test.js +0 -162
  62. package/dist/test/06.feegrant_tx.test.d.ts +0 -1
  63. package/dist/test/06.feegrant_tx.test.js +0 -185
  64. package/dist/test/07.feegrant_query.test.d.ts +0 -1
  65. package/dist/test/07.feegrant_query.test.js +0 -129
  66. package/dist/test/08.gas_estimate.test.d.ts +0 -1
  67. package/dist/test/08.gas_estimate.test.js +0 -728
  68. package/dist/test/09.ipfs.test.d.ts +0 -1
  69. package/dist/test/09.ipfs.test.js +0 -72
  70. package/dist/test/10.nft_tx.test.d.ts +0 -1
  71. package/dist/test/10.nft_tx.test.js +0 -209
  72. package/dist/test/11.nft_query.test.d.ts +0 -1
  73. package/dist/test/11.nft_query.test.js +0 -165
  74. package/dist/test/12.staking_tx.test.d.ts +0 -1
  75. package/dist/test/12.staking_tx.test.js +0 -211
  76. package/dist/test/13.staking_query.test.d.ts +0 -1
  77. package/dist/test/13.staking_query.test.js +0 -275
  78. package/dist/test/14.distribution_tx.test.d.ts +0 -1
  79. package/dist/test/14.distribution_tx.test.js +0 -170
  80. package/dist/test/15.distribution_query.test.d.ts +0 -1
  81. package/dist/test/15.distribution_query.test.js +0 -243
  82. package/dist/test/16.gov_tx.test.d.ts +0 -1
  83. package/dist/test/16.gov_tx.test.js +0 -394
  84. package/dist/test/17.gov_query.test.d.ts +0 -1
  85. package/dist/test/17.gov_query.test.js +0 -181
  86. package/dist/test/18.util.test.d.ts +0 -1
  87. package/dist/test/18.util.test.js +0 -354
  88. package/dist/test/19.chain.test.d.ts +0 -1
  89. package/dist/test/19.chain.test.js +0 -127
  90. package/dist/test/20.slashing_query.test.d.ts +0 -1
  91. package/dist/test/20.slashing_query.test.js +0 -111
  92. package/dist/test/21.token_tx.test.d.ts +0 -1
  93. package/dist/test/21.token_tx.test.js +0 -149
  94. package/dist/test/22.token_query.test.d.ts +0 -1
  95. package/dist/test/22.token_query.test.js +0 -103
  96. package/dist/test/23.authz_tx.test.d.ts +0 -1
  97. package/dist/test/23.authz_tx.test.js +0 -380
  98. package/dist/test/24.authz_query.test.d.ts +0 -1
  99. package/dist/test/24.authz_query.test.js +0 -202
  100. package/dist/test/25.cosmwasm_tx.test.d.ts +0 -1
  101. package/dist/test/25.cosmwasm_tx.test.js +0 -229
  102. package/dist/test/26.cosmwasm_query.test.d.ts +0 -1
  103. package/dist/test/26.cosmwasm_query.test.js +0 -275
  104. package/dist/test/27.arbitrary_sign.test.d.ts +0 -1
  105. package/dist/test/27.arbitrary_sign.test.js +0 -162
  106. package/dist/test/28.ibc_tx.test.d.ts +0 -1
  107. package/dist/test/28.ibc_tx.test.js +0 -98
  108. package/dist/test/29.mint_query.test.d.ts +0 -1
  109. package/dist/test/29.mint_query.test.js +0 -59
  110. package/dist/test/30.cw20_tx.test.d.ts +0 -1
  111. package/dist/test/30.cw20_tx.test.js +0 -450
  112. package/dist/test/31.cw20_query.test.d.ts +0 -1
  113. package/dist/test/31.cw20_query.test.js +0 -333
  114. package/dist/test/32.cw721_tx.test.d.ts +0 -1
  115. package/dist/test/32.cw721_tx.test.js +0 -431
  116. package/dist/test/33.cw721_query.test.d.ts +0 -1
  117. package/dist/test/33.cw721_query.test.js +0 -371
  118. package/dist/test/34.cw_bridge_tx.test.d.ts +0 -1
  119. package/dist/test/34.cw_bridge_tx.test.js +0 -476
  120. package/dist/test/35.cw_bridge_tx_low.test.d.ts +0 -1
  121. package/dist/test/35.cw_bridge_tx_low.test.js +0 -398
  122. package/dist/test/36.cw_bridge_query.test.d.ts +0 -1
  123. package/dist/test/36.cw_bridge_query.test.js +0 -318
  124. package/dist/test/37.cw_marketplace_tx.test.d.ts +0 -1
  125. package/dist/test/37.cw_marketplace_tx.test.js +0 -794
  126. package/dist/test/38.cw_marketplace_query.test.d.ts +0 -1
  127. package/dist/test/38.cw_marketplace_query.test.js +0 -128
  128. package/dist/test/config_test.d.ts +0 -11
  129. package/dist/test/config_test.js +0 -26
  130. package/dist/test/config_test.sample.d.ts +0 -11
  131. package/dist/test/config_test.sample.js +0 -14
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -35,6 +46,17 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
46
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
47
  }
37
48
  };
49
+ var __values = (this && this.__values) || function(o) {
50
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
51
+ if (m) return m.call(o);
52
+ if (o && typeof o.length === "number") return {
53
+ next: function () {
54
+ if (o && i >= o.length) o = void 0;
55
+ return { value: o && o[i++], done: !o };
56
+ }
57
+ };
58
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
59
+ };
38
60
  var __read = (this && this.__read) || function (o, n) {
39
61
  var m = typeof Symbol === "function" && o[Symbol.iterator];
40
62
  if (!m) return o;
@@ -60,154 +82,1274 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
60
82
  }
61
83
  return to.concat(ar || Array.prototype.slice.call(from));
62
84
  };
63
- var __values = (this && this.__values) || function(o) {
64
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
65
- if (m) return m.call(o);
66
- if (o && typeof o.length === "number") return {
67
- next: function () {
68
- if (o && i >= o.length) o = void 0;
69
- return { value: o && o[i++], done: !o };
70
- }
71
- };
72
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
73
- };
85
+ var _a, _b;
74
86
  Object.defineProperty(exports, "__esModule", { value: true });
75
- exports.signWithSignerProtobuf = void 0;
87
+ exports.signWithSignerTextual = exports.buildSimulationTxRawLedger = exports.signWithSignerAuto = exports.signWithSignerAmino = void 0;
88
+ var crypto_1 = require("@cosmjs/crypto");
76
89
  var signing_1 = require("cosmjs-types/cosmos/tx/signing/v1beta1/signing");
77
90
  var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
78
- var encoding_1 = require("@cosmjs/encoding");
79
91
  var keys_1 = require("cosmjs-types/cosmos/crypto/secp256k1/keys");
80
- // Creates AuthInfoBytes for "SIGN_MODE_DIRECT"
81
- function makeAuthInfoBytesDirect(pubkey, feeAmount, gasLimit, sequence) {
82
- var signerInfo = {
83
- publicKey: pubkey,
84
- modeInfo: {
85
- single: { mode: signing_1.SignMode.SIGN_MODE_DIRECT },
86
- },
87
- sequence: BigInt(sequence),
88
- };
89
- var authInfo = {
90
- signerInfos: [signerInfo],
91
- fee: {
92
- amount: __spreadArray([], __read(feeAmount), false),
93
- gasLimit: BigInt(gasLimit),
94
- },
95
- };
96
- return tx_1.AuthInfo.encode(tx_1.AuthInfo.fromPartial(authInfo)).finish();
97
- }
98
- /**
99
- * Signs a protobuf-based Cosmos transaction using a general Signer
100
- * compatible with SIGN_MODE_DIRECT (e.g. Ledger, Keplr, etc.)
101
- *
102
- * @param signer - SignerInterface instance
103
- * @param messages - Cosmos transaction messages
104
- * @param signerData - Chain ID, account number, sequence
105
- * @param option - Fee, memo, granter info
106
- * @param registry - Protobuf registry for message encoding
107
- * @returns TxRaw - fully signed transaction
108
- */
109
- function signWithSignerProtobuf(signer, messages, signerData, option, registry) {
92
+ var tx_2 = require("cosmjs-types/cosmos/distribution/v1beta1/tx");
93
+ var tx_3 = require("cosmjs-types/cosmos/staking/v1beta1/tx");
94
+ var authz_1 = require("cosmjs-types/cosmos/staking/v1beta1/authz");
95
+ var authz_2 = require("cosmjs-types/cosmos/bank/v1beta1/authz");
96
+ var authz_3 = require("cosmjs-types/cosmos/authz/v1beta1/authz");
97
+ var feegrant_1 = require("cosmjs-types/cosmos/feegrant/v1beta1/feegrant");
98
+ var tx_4 = require("@kintsugi-tech/cosmjs-types/cosmos/gov/v1/tx");
99
+ var tx_5 = require("@kintsugi-tech/cosmjs-types/cosmos/upgrade/v1beta1/tx");
100
+ var amino_1 = require("@cosmjs/amino");
101
+ var stargate_1 = require("@cosmjs/stargate");
102
+ var signing_2 = require("./signing");
103
+ // Two-tier Ledger debug logging.
104
+ //
105
+ // DEBUG_LEDGER=1 — structural tracing only: connect events, typeUrl, field
106
+ // names. Does NOT expose transaction contents. Safe to enable in shared
107
+ // staging environments.
108
+ //
109
+ // DEBUG_LEDGER_CBOR=1 — full transaction dump: rendered screens (addresses,
110
+ // amounts, memos) and CBOR hex bytes. Reveals every detail of the tx being
111
+ // signed. Do NOT enable in production or on shared hosts.
112
+ var DEBUG_LEDGER = (typeof process !== "undefined" && ((_a = process.env) === null || _a === void 0 ? void 0 : _a.DEBUG_LEDGER) === "1") ||
113
+ (typeof globalThis !== "undefined" && globalThis.DEBUG_LEDGER === true);
114
+ var DEBUG_LEDGER_CBOR = (typeof process !== "undefined" && ((_b = process.env) === null || _b === void 0 ? void 0 : _b.DEBUG_LEDGER_CBOR) === "1") ||
115
+ (typeof globalThis !== "undefined" && globalThis.DEBUG_LEDGER_CBOR === true);
116
+ // ─── Minimal CBOR encoder ────────────────────────────────────────────────────
117
+ function concatBytes() {
118
+ var e_1, _a;
119
+ var arrays = [];
120
+ for (var _i = 0; _i < arguments.length; _i++) {
121
+ arrays[_i] = arguments[_i];
122
+ }
123
+ var total = arrays.reduce(function (acc, a) { return acc + a.length; }, 0);
124
+ var out = new Uint8Array(total);
125
+ var off = 0;
126
+ try {
127
+ for (var arrays_1 = __values(arrays), arrays_1_1 = arrays_1.next(); !arrays_1_1.done; arrays_1_1 = arrays_1.next()) {
128
+ var a = arrays_1_1.value;
129
+ out.set(a, off);
130
+ off += a.length;
131
+ }
132
+ }
133
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
134
+ finally {
135
+ try {
136
+ if (arrays_1_1 && !arrays_1_1.done && (_a = arrays_1.return)) _a.call(arrays_1);
137
+ }
138
+ finally { if (e_1) throw e_1.error; }
139
+ }
140
+ return out;
141
+ }
142
+ function cborMajorN(major, n) {
143
+ var type = major << 5;
144
+ if (n <= 23)
145
+ return new Uint8Array([type | n]);
146
+ if (n <= 0xff)
147
+ return new Uint8Array([type | 24, n]);
148
+ if (n <= 0xffff)
149
+ return new Uint8Array([type | 25, (n >> 8) & 0xff, n & 0xff]);
150
+ var b = new Uint8Array(5);
151
+ b[0] = type | 26;
152
+ new DataView(b.buffer).setUint32(1, n, false);
153
+ return b;
154
+ }
155
+ function cborUint(n) { return cborMajorN(0, n); }
156
+ function cborText(s) {
157
+ var utf8 = new TextEncoder().encode(s);
158
+ return concatBytes(cborMajorN(3, utf8.length), utf8);
159
+ }
160
+ function encodeSingleScreen(s) {
161
+ var parts = [];
162
+ var n = 0;
163
+ if (s.title) {
164
+ parts.push(cborUint(1), cborText(s.title));
165
+ n++;
166
+ }
167
+ // always include content: Ledger parser requires key 2 after key 1 (title)
168
+ parts.push(cborUint(2), cborText(s.content));
169
+ n++;
170
+ if (s.indent && s.indent > 0) {
171
+ parts.push(cborUint(3), cborUint(s.indent));
172
+ n++;
173
+ }
174
+ if (s.expert) {
175
+ parts.push(cborUint(4), new Uint8Array([0xf5]));
176
+ n++;
177
+ }
178
+ return concatBytes.apply(void 0, __spreadArray([cborMajorN(5, n)], __read(parts), false));
179
+ }
180
+ function encodeTextualCbor(screens) {
181
+ var items = screens.map(encodeSingleScreen);
182
+ var arr = concatBytes.apply(void 0, __spreadArray([cborMajorN(4, screens.length)], __read(items), false));
183
+ return concatBytes(cborMajorN(5, 1), cborUint(1), arr);
184
+ }
185
+ function queryCoinMetadata(restUrl, denom) {
186
+ var _a;
110
187
  return __awaiter(this, void 0, void 0, function () {
111
- var anyMsgs, txBody, bodyBytes, pubkey, pubkeyProto, feeAmount, authInfoBytes, signDoc, signDocBytes, base64SignBytes, signature, lastError, protobufAttempts, protobufAttempts_1, protobufAttempts_1_1, attempt, signError_1, e_1_1, errorMsg, txRaw;
112
- var e_1, _a;
113
- return __generator(this, function (_b) {
114
- switch (_b.label) {
188
+ var resp, data, _b;
189
+ return __generator(this, function (_c) {
190
+ switch (_c.label) {
115
191
  case 0:
116
- anyMsgs = messages.map(function (msg) { return registry.encodeAsAny(msg); });
117
- txBody = tx_1.TxBody.fromPartial({
118
- messages: anyMsgs,
119
- memo: option.memo || "",
120
- });
121
- bodyBytes = tx_1.TxBody.encode(txBody).finish();
122
- return [4 /*yield*/, signer.getPublicKey()];
192
+ if (!restUrl)
193
+ return [2 /*return*/, null];
194
+ _c.label = 1;
195
+ case 1:
196
+ _c.trys.push([1, 4, , 5]);
197
+ return [4 /*yield*/, fetch("".concat(restUrl, "/cosmos/bank/v1beta1/denoms_metadata/").concat(encodeURIComponent(denom)))];
198
+ case 2:
199
+ resp = _c.sent();
200
+ if (!resp.ok)
201
+ return [2 /*return*/, null];
202
+ return [4 /*yield*/, resp.json()];
203
+ case 3:
204
+ data = _c.sent();
205
+ return [2 /*return*/, (_a = data.metadata) !== null && _a !== void 0 ? _a : null];
206
+ case 4:
207
+ _b = _c.sent();
208
+ return [2 /*return*/, null];
209
+ case 5: return [2 /*return*/];
210
+ }
211
+ });
212
+ });
213
+ }
214
+ // Matches cosmos SDK math.FormatInt: adds apostrophe thousand separators
215
+ function formatIntWithSep(v) {
216
+ var neg = v.startsWith("-");
217
+ var digits = neg ? v.slice(1) : v;
218
+ if (digits.length <= 3)
219
+ return v;
220
+ var groups = [];
221
+ var mod3 = digits.length % 3;
222
+ var i = 0;
223
+ if (mod3 !== 0) {
224
+ groups.push(digits.slice(0, mod3));
225
+ i = mod3;
226
+ }
227
+ while (i < digits.length) {
228
+ groups.push(digits.slice(i, i + 3));
229
+ i += 3;
230
+ }
231
+ return (neg ? "-" : "") + groups.join("'");
232
+ }
233
+ function formatOneCoin(amount, denom, meta) {
234
+ if (!meta)
235
+ return "".concat(formatIntWithSep(amount), " ").concat(denom);
236
+ var baseUnit = meta.denom_units.find(function (u) { return u.denom === denom; });
237
+ var displayName = meta.display;
238
+ var displayUnit = meta.denom_units.find(function (u) { return u.denom === displayName || u.denom === displayName.toLowerCase(); });
239
+ if (!baseUnit || !displayUnit)
240
+ return "".concat(formatIntWithSep(amount), " ").concat(displayName || denom);
241
+ var exp = displayUnit.exponent - baseUnit.exponent;
242
+ if (exp <= 0)
243
+ return "".concat(formatIntWithSep(amount), " ").concat(displayName);
244
+ var factor = BigInt(Math.pow(10, exp));
245
+ var big = BigInt(amount);
246
+ var whole = big / factor;
247
+ var rem = big % factor;
248
+ if (rem === BigInt(0))
249
+ return "".concat(formatIntWithSep(whole.toString()), " ").concat(displayName);
250
+ var decimals = rem.toString().padStart(exp, "0").replace(/0+$/, "");
251
+ return "".concat(formatIntWithSep(whole.toString()), ".").concat(decimals, " ").concat(displayName);
252
+ }
253
+ function formatCoins(coins, restUrl) {
254
+ return __awaiter(this, void 0, void 0, function () {
255
+ var parts;
256
+ var _this = this;
257
+ return __generator(this, function (_a) {
258
+ switch (_a.label) {
259
+ case 0:
260
+ if (coins.length === 0)
261
+ return [2 /*return*/, "0"];
262
+ return [4 /*yield*/, Promise.all(coins.map(function (c) { return __awaiter(_this, void 0, void 0, function () {
263
+ var meta;
264
+ return __generator(this, function (_a) {
265
+ switch (_a.label) {
266
+ case 0: return [4 /*yield*/, queryCoinMetadata(restUrl, c.denom)];
267
+ case 1:
268
+ meta = _a.sent();
269
+ return [2 /*return*/, formatOneCoin(c.amount, c.denom, meta)];
270
+ }
271
+ });
272
+ }); }))];
123
273
  case 1:
124
- pubkey = _b.sent();
274
+ parts = _a.sent();
275
+ return [2 /*return*/, parts.join(", ")];
276
+ }
277
+ });
278
+ });
279
+ }
280
+ // ─── Formatting helpers ───────────────────────────────────────────────────────
281
+ function formatPubkeyHex(pubkey) {
282
+ var hex = Buffer.from(pubkey).toString("hex").toUpperCase();
283
+ var groups = [];
284
+ for (var i = 0; i < hex.length; i += 4)
285
+ groups.push(hex.slice(i, i + 4));
286
+ return groups.join(" ");
287
+ }
288
+ function formatGasLimit(gas) {
289
+ return BigInt(gas).toString().replace(/\B(?=(\d{3})+(?!\d))/g, "'");
290
+ }
291
+ function computeRawBytesHash(bodyBytes, authInfoBytes) {
292
+ var buf = new Uint8Array(8 + bodyBytes.length + 8 + authInfoBytes.length);
293
+ var view = new DataView(buf.buffer);
294
+ view.setBigUint64(0, BigInt(bodyBytes.length), false);
295
+ buf.set(bodyBytes, 8);
296
+ view.setBigUint64(8 + bodyBytes.length, BigInt(authInfoBytes.length), false);
297
+ buf.set(authInfoBytes, 8 + bodyBytes.length + 8);
298
+ return Buffer.from((0, crypto_1.sha256)(buf)).toString("hex");
299
+ }
300
+ // Cosmos SDK's formatFieldName splits the proto field name on underscore and
301
+ // title-cases only the first word (preserving inner casing with NoLower). So:
302
+ // standard Cosmos proto `from_address` → "From address"
303
+ // Firma custom proto `tokenURI` → "TokenURI" (no underscore → one word)
304
+ // cosmjs-types TS bindings expose field names in camelCase either way, so we
305
+ // can't derive the proto style from the TS key alone — `fromAddress` could come
306
+ // from `from_address` or `fromAddress`. Instead we key off parentTypeUrl: every
307
+ // Firma custom module declares fields in camelCase, so for `/firmachain.*` we
308
+ // preserve the TS key verbatim (just capitalize the first letter). Other
309
+ // prefixes (cosmos, ibc, etc.) follow the standard Cosmos convention of
310
+ // converting camelCase TS → snake proto → sentence case.
311
+ function fieldToDisplayName(name, parentTypeUrl) {
312
+ if (parentTypeUrl && parentTypeUrl.startsWith("/firmachain.")) {
313
+ return name.charAt(0).toUpperCase() + name.slice(1);
314
+ }
315
+ var snake = name
316
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
317
+ .replace(/([a-z])([A-Z])/g, "$1_$2")
318
+ .toLowerCase()
319
+ .replace(/^_/, "");
320
+ return snake.replace(/_/g, " ").replace(/^./, function (c) { return c.toUpperCase(); });
321
+ }
322
+ // Returns true if v is a plain proto message object (not Duration, Coin, Any, array, or primitive)
323
+ function isPlainProtoMessage(v) {
324
+ if (typeof v !== "object" || v === null || Array.isArray(v))
325
+ return false;
326
+ if ("seconds" in v)
327
+ return false; // Duration / Timestamp
328
+ if ("denom" in v && "amount" in v)
329
+ return false; // Coin
330
+ if ("typeUrl" in v)
331
+ return false; // Any
332
+ return true;
333
+ }
334
+ var VOTE_OPTION_NAMES = {
335
+ 0: "VOTE_OPTION_UNSPECIFIED",
336
+ 1: "VOTE_OPTION_YES",
337
+ 2: "VOTE_OPTION_ABSTAIN",
338
+ 3: "VOTE_OPTION_NO",
339
+ 4: "VOTE_OPTION_NO_WITH_VETO",
340
+ };
341
+ // Cosmos textual renders enum values as their symbolic name (via fd.Enum()), not
342
+ // as the numeric wire value. Decoded proto objects give us only the number, so
343
+ // we map it back to the canonical name here. Without this, authz stake grants
344
+ // rendered the authorizationType as "1" instead of "AUTHORIZATION_TYPE_DELEGATE"
345
+ // and failed TEXTUAL signature verification.
346
+ var STAKE_AUTHORIZATION_TYPE_NAMES = {
347
+ 0: "AUTHORIZATION_TYPE_UNSPECIFIED",
348
+ 1: "AUTHORIZATION_TYPE_DELEGATE",
349
+ 2: "AUTHORIZATION_TYPE_UNDELEGATE",
350
+ 3: "AUTHORIZATION_TYPE_REDELEGATE",
351
+ 4: "AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION",
352
+ };
353
+ function isLongObject(v) {
354
+ return typeof v === "object" && v !== null && "low" in v && "high" in v && typeof v.toString === "function";
355
+ }
356
+ // Converts Uint8Array or a JSON-serialized numeric-keyed object back to Uint8Array
357
+ function toUint8ArraySafe(v) {
358
+ var e_2, _a;
359
+ if (v instanceof Uint8Array)
360
+ return v;
361
+ if (Buffer.isBuffer(v))
362
+ return new Uint8Array(v);
363
+ if (typeof v === "object" && v !== null && !Array.isArray(v)) {
364
+ var obj_1 = v;
365
+ var keys = Object.keys(obj_1);
366
+ if (keys.length > 0 && keys.every(function (k) { return !isNaN(Number(k)) && typeof obj_1[k] === "number"; })) {
367
+ var arr = new Uint8Array(keys.length);
368
+ try {
369
+ for (var keys_2 = __values(keys), keys_2_1 = keys_2.next(); !keys_2_1.done; keys_2_1 = keys_2.next()) {
370
+ var k = keys_2_1.value;
371
+ arr[Number(k)] = obj_1[k];
372
+ }
373
+ }
374
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
375
+ finally {
376
+ try {
377
+ if (keys_2_1 && !keys_2_1.done && (_a = keys_2.return)) _a.call(keys_2);
378
+ }
379
+ finally { if (e_2) throw e_2.error; }
380
+ }
381
+ return arr;
382
+ }
383
+ }
384
+ return null;
385
+ }
386
+ // Converts proto Duration { seconds: bigint, nanos: number } to amino nanoseconds string
387
+ function durationToAminoNanos(d) {
388
+ var _a;
389
+ return (BigInt(d.seconds.toString()) * BigInt(1000000000) + BigInt((_a = d.nanos) !== null && _a !== void 0 ? _a : 0)).toString();
390
+ }
391
+ // Renders proto Duration as human-readable string (matches Cosmos SDK textual renderer).
392
+ // NOTE: parts are joined with ", " (comma + space), not just space. Cosmos SDK's
393
+ // duration renderer uses comma-separated components; an earlier version of this
394
+ // function joined with " " which produced "5 minutes 1 second" instead of the
395
+ // chain's "5 minutes, 1 second" and broke TEXTUAL signature verification for any
396
+ // message containing a non-trivial Duration (gov Params Update was the trigger).
397
+ function renderDuration(d) {
398
+ var totalSeconds = BigInt(d.seconds.toString());
399
+ var days = totalSeconds / BigInt(86400);
400
+ totalSeconds -= days * BigInt(86400);
401
+ var hours = totalSeconds / BigInt(3600);
402
+ totalSeconds -= hours * BigInt(3600);
403
+ var minutes = totalSeconds / BigInt(60);
404
+ var seconds = totalSeconds - minutes * BigInt(60);
405
+ var parts = [];
406
+ if (days > BigInt(0))
407
+ parts.push("".concat(days, " day").concat(days === BigInt(1) ? "" : "s"));
408
+ if (hours > BigInt(0))
409
+ parts.push("".concat(hours, " hour").concat(hours === BigInt(1) ? "" : "s"));
410
+ if (minutes > BigInt(0))
411
+ parts.push("".concat(minutes, " minute").concat(minutes === BigInt(1) ? "" : "s"));
412
+ if (seconds > BigInt(0))
413
+ parts.push("".concat(seconds, " second").concat(seconds === BigInt(1) ? "" : "s"));
414
+ return parts.length > 0 ? parts.join(", ") : "0 seconds";
415
+ }
416
+ // Renders proto Timestamp as RFC3339Nano (matches Cosmos SDK textual renderer
417
+ // time.Format(time.RFC3339Nano) — trailing zeros of subsecond precision trimmed).
418
+ // Added because google.protobuf.Timestamp and google.protobuf.Duration share the
419
+ // {seconds, nanos} shape, and the renderer previously treated every such object
420
+ // as a Duration. That produced e.g. "20930 days, 11 hours, 10 minutes, 25 seconds"
421
+ // for an authz.Grant.expiration Timestamp, while the chain reconstructed the
422
+ // equivalent RFC3339 string ("2027-04-22T11:10:25Z") — CBOR bytes diverged and
423
+ // signature verification failed with `code 4 unauthorized`.
424
+ function renderTimestamp(t) {
425
+ var _a;
426
+ var secs = BigInt(t.seconds.toString());
427
+ var nanos = (_a = t.nanos) !== null && _a !== void 0 ? _a : 0;
428
+ var ms = Number(secs) * 1000;
429
+ var iso = new Date(ms).toISOString();
430
+ if (nanos === 0) {
431
+ return iso.replace(/\.\d+Z$/, "Z");
432
+ }
433
+ var nanoStr = String(nanos).padStart(9, "0").replace(/0+$/, "");
434
+ return iso.replace(/\.\d+Z$/, ".".concat(nanoStr, "Z"));
435
+ }
436
+ // Proto fields that carry google.protobuf.Timestamp (not Duration). Both have
437
+ // the same {seconds, nanos} shape, so field name is the only disambiguator
438
+ // unless we thread proto type info through the renderer.
439
+ var TIMESTAMP_FIELD_NAMES = new Set([
440
+ "expiration", "expirationTime", "expiration_time",
441
+ "periodReset", "period_reset",
442
+ "time",
443
+ ]);
444
+ // cosmos.Dec may reach us as either form:
445
+ // (a) raw 18-decimal fixed-point integer string ("334000000000000000")
446
+ // (b) already-formatted decimal string ("0.334000000000000000") — this is what
447
+ // Cosmos SDK's Dec.String() produces and what REST/LCD returns.
448
+ // Both must render to the Cosmos textual form: integer part with ' thousand
449
+ // separators, trailing fractional zeros stripped (e.g. "1'234.56", "0.334").
450
+ //
451
+ // The earlier implementation assumed (a) only. Given input "0.334000000000000000"
452
+ // it produced "0..334" (the leading "0." was treated as the integer slice and a
453
+ // second "." was injected as the decimal separator), breaking TEXTUAL signature
454
+ // verification for gov.Params (quorum/threshold/etc.) update proposals submitted
455
+ // from firma-station where the params come through pre-formatted from the chain.
456
+ function renderCosmosDecString(s) {
457
+ var neg = s.startsWith("-");
458
+ var raw = neg ? s.slice(1) : s;
459
+ var intPart;
460
+ var fracPart;
461
+ if (raw.includes(".")) {
462
+ var _a = __read(raw.split("."), 2), intPartRaw = _a[0], _b = _a[1], fracPartRaw = _b === void 0 ? "" : _b;
463
+ intPart = intPartRaw.replace(/^0+/, "") || "0";
464
+ fracPart = fracPartRaw.replace(/0+$/, "");
465
+ }
466
+ else {
467
+ var DEC_PRECISION = 18;
468
+ var padded = raw.padStart(DEC_PRECISION + 1, "0");
469
+ intPart = (padded.slice(0, padded.length - DEC_PRECISION).replace(/^0+/, "") || "0");
470
+ fracPart = padded.slice(padded.length - DEC_PRECISION).replace(/0+$/, "");
471
+ }
472
+ var intFormatted = formatIntWithSep(intPart);
473
+ return (neg ? "-" : "") + (fracPart ? "".concat(intFormatted, ".").concat(fracPart) : intFormatted);
474
+ }
475
+ // Fields known to carry cosmos.Dec values (18-decimal fixed-point strings)
476
+ var COSMOS_DEC_FIELDS = new Set([
477
+ "minCommissionRate", "min_commission_rate",
478
+ "quorum", "threshold", "vetoThreshold", "veto_threshold",
479
+ "minInitialDepositRatio", "min_initial_deposit_ratio",
480
+ "proposalCancelRatio", "proposal_cancel_ratio",
481
+ "expeditedThreshold", "expedited_threshold",
482
+ "minDepositRatio", "min_deposit_ratio",
483
+ ]);
484
+ // Fallback decoders for Any-wrapped messages that the per-tx Registry may not
485
+ // know about. TEXTUAL rendering must descend into the inner message and emit
486
+ // each sub-field as its own screen; without a decoder here we would render only
487
+ // the Any typeUrl and omit every sub-field — which leaves our CBOR shorter than
488
+ // the chain's reconstruction and causes `code 4 unauthorized`. The Authorization
489
+ // entries were added specifically for authz Grant flows (stake delegate grant).
490
+ // Entries are typed via `[string, NestedDecoder]` to prevent TS from narrowing
491
+ // the value type to the first entry's proto class (which would then reject the
492
+ // rest, since each proto's `encode` signature accepts a different message shape).
493
+ var NESTED_ANY_DECODERS = new Map([
494
+ ["/cosmos.distribution.v1beta1.MsgCommunityPoolSpend", tx_2.MsgCommunityPoolSpend],
495
+ ["/cosmos.staking.v1beta1.MsgUpdateParams", tx_3.MsgUpdateParams],
496
+ ["/cosmos.staking.v1beta1.StakeAuthorization", authz_1.StakeAuthorization],
497
+ ["/cosmos.bank.v1beta1.SendAuthorization", authz_2.SendAuthorization],
498
+ ["/cosmos.authz.v1beta1.GenericAuthorization", authz_3.GenericAuthorization],
499
+ ["/cosmos.feegrant.v1beta1.BasicAllowance", feegrant_1.BasicAllowance],
500
+ ["/cosmos.feegrant.v1beta1.PeriodicAllowance", feegrant_1.PeriodicAllowance],
501
+ ["/cosmos.feegrant.v1beta1.AllowedMsgAllowance", feegrant_1.AllowedMsgAllowance],
502
+ ["/cosmos.gov.v1.MsgUpdateParams", tx_4.MsgUpdateParams],
503
+ ["/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade", tx_5.MsgSoftwareUpgrade],
504
+ ]);
505
+ function lookupNestedDecoder(typeUrl, registry) {
506
+ var _a;
507
+ try {
508
+ var t = registry.lookupType(typeUrl);
509
+ if (t)
510
+ return t;
511
+ }
512
+ catch (_b) { }
513
+ return (_a = NESTED_ANY_DECODERS.get(typeUrl)) !== null && _a !== void 0 ? _a : null;
514
+ }
515
+ function isSingleAnyObject(v) {
516
+ return (typeof v === "object" &&
517
+ v !== null &&
518
+ !Array.isArray(v) &&
519
+ "typeUrl" in v &&
520
+ "value" in v &&
521
+ typeof v.typeUrl === "string");
522
+ }
523
+ // Cosmos textual Any renderer: replace "{Type} object" header with the typeUrl
524
+ // content, then recursively render the inner message's fields at indent+1.
525
+ //
526
+ // Added because previously `renderFieldValue` for an Any object returned only
527
+ // the typeUrl as a single string and never descended into sub-fields. This was
528
+ // fine for repeated-Any fields (MsgSubmitProposal.messages handled separately),
529
+ // but broke on single-Any fields such as authz.Grant.authorization. The chain's
530
+ // textual renderer always expands the Any body, so dropping the sub-fields on
531
+ // the wallet side left the CBOR short and signatures unverifiable.
532
+ function renderSingleAnyField(fieldName, any, baseIndent, registry, restUrl, screens, parentTypeUrl) {
533
+ return __awaiter(this, void 0, void 0, function () {
534
+ var decoder, valueBytes, nested, e_3;
535
+ return __generator(this, function (_a) {
536
+ switch (_a.label) {
537
+ case 0:
538
+ screens.push({ title: fieldToDisplayName(fieldName, parentTypeUrl), content: any.typeUrl, indent: baseIndent });
539
+ decoder = lookupNestedDecoder(any.typeUrl, registry);
540
+ valueBytes = toUint8ArraySafe(any.value);
541
+ if (!decoder || !valueBytes) {
542
+ if (!decoder)
543
+ console.warn('[Textual] no decoder for nested Any:', any.typeUrl);
544
+ return [2 /*return*/];
545
+ }
546
+ _a.label = 1;
547
+ case 1:
548
+ _a.trys.push([1, 3, , 4]);
549
+ nested = decoder.decode(valueBytes);
550
+ return [4 /*yield*/, renderMessageFields(nested, baseIndent + 1, registry, restUrl, screens, any.typeUrl)];
551
+ case 2:
552
+ _a.sent();
553
+ return [3 /*break*/, 4];
554
+ case 3:
555
+ e_3 = _a.sent();
556
+ console.warn('[Textual] nested Any decode error for', any.typeUrl, ':', e_3);
557
+ return [3 /*break*/, 4];
558
+ case 4: return [2 /*return*/];
559
+ }
560
+ });
561
+ });
562
+ }
563
+ // Scalar kind label for Cosmos textual formatRepeated.
564
+ // Matches Go's toSentenceCase(fd.Kind().String()) — first letter capitalized,
565
+ // NO pluralization regardless of count (e.g. "3 String", "1 Any", "2 Int64").
566
+ function getScalarKindLabel(item) {
567
+ if (typeof item === "string")
568
+ return "String";
569
+ if (typeof item === "boolean")
570
+ return "Bool";
571
+ if (typeof item === "number" || typeof item === "bigint")
572
+ return "Int64";
573
+ if (isLongObject(item))
574
+ return "Int64";
575
+ if (item instanceof Uint8Array)
576
+ return "Bytes";
577
+ return "Item";
578
+ }
579
+ // Renders a repeated scalar/primitive field (repeated string, int, bool, etc.)
580
+ // as cosmos textual formatRepeated output:
581
+ // "{Title}: {N} {Kind}" (kind is capitalized singular, no plural)
582
+ // "{Title} (1/N): {value}"
583
+ // ...
584
+ // "End of {Title}"
585
+ //
586
+ // Added for authz StakeAuthorization.Validators.address (repeated string). The
587
+ // old fallback in renderFieldValue JSON-stringified the array to a single line
588
+ // ('["firmavaloper1...", ...]'), which the chain's textual renderer does NOT
589
+ // produce — it emits the count header + per-item screens + terminal. Mismatch
590
+ // → signature verification failed.
591
+ function renderRepeatedScalar(fieldName, items, baseIndent, restUrl, screens, parentTypeUrl) {
592
+ return __awaiter(this, void 0, void 0, function () {
593
+ var count, kind, title, i, itemTitle, content;
594
+ return __generator(this, function (_a) {
595
+ switch (_a.label) {
596
+ case 0:
597
+ count = items.length;
598
+ kind = getScalarKindLabel(items[0]);
599
+ title = fieldToDisplayName(fieldName, parentTypeUrl);
600
+ screens.push({ title: title, content: "".concat(count, " ").concat(kind), indent: baseIndent });
601
+ i = 0;
602
+ _a.label = 1;
603
+ case 1:
604
+ if (!(i < count)) return [3 /*break*/, 4];
605
+ itemTitle = "".concat(title, " (").concat(i + 1, "/").concat(count, ")");
606
+ return [4 /*yield*/, renderFieldValue(items[i], restUrl, fieldName, parentTypeUrl)];
607
+ case 2:
608
+ content = _a.sent();
609
+ screens.push({ title: itemTitle, content: content, indent: baseIndent + 1 });
610
+ _a.label = 3;
611
+ case 3:
612
+ i++;
613
+ return [3 /*break*/, 1];
614
+ case 4:
615
+ screens.push({ content: "End of ".concat(title), indent: baseIndent });
616
+ return [2 /*return*/];
617
+ }
618
+ });
619
+ });
620
+ }
621
+ // True for arrays that should render as formatRepeated multi-screen (not a single
622
+ // comma-joined line like Coin arrays). Applies to primitives and plain messages.
623
+ function isMultiScreenRepeated(v) {
624
+ if (v.length === 0)
625
+ return false;
626
+ var first = v[0];
627
+ if (typeof first === "string")
628
+ return true;
629
+ if (typeof first === "boolean")
630
+ return true;
631
+ if (typeof first === "number" || typeof first === "bigint")
632
+ return true;
633
+ if (isLongObject(first))
634
+ return true;
635
+ return false;
636
+ }
637
+ // Mirrors proto3 "default value skipping" — the chain's textual renderer
638
+ // omits fields that are at their proto3 default (proto3 doesn't write defaults
639
+ // to the wire, so the chain's Message.Has(fd) returns false for them). If the
640
+ // wallet renders them anyway, our CBOR gains extra screens the chain never
641
+ // produces and signature verification fails. The Any/Timestamp/Uint8Array
642
+ // entries below were added incrementally as failure modes surfaced (most
643
+ // notably Plan.upgraded_client_state, an empty Any that blocked Software
644
+ // Upgrade proposals).
645
+ function shouldSkipField(v) {
646
+ var _a;
647
+ if (v === "" || v === false)
648
+ return true;
649
+ if (Array.isArray(v) && v.length === 0)
650
+ return true;
651
+ if (v === 0 || v === BigInt(0))
652
+ return true;
653
+ if (v === null || v === undefined)
654
+ return true;
655
+ if (isLongObject(v) && v.low === 0 && v.high === 0)
656
+ return true;
657
+ if (v instanceof Uint8Array && v.length === 0)
658
+ return true;
659
+ if (typeof v === "object" && v !== null && "seconds" in v && !Array.isArray(v)) {
660
+ var dur = v;
661
+ if (BigInt(dur.seconds.toString()) === BigInt(0) && ((_a = dur.nanos) !== null && _a !== void 0 ? _a : 0) === 0)
662
+ return true;
663
+ }
664
+ if (typeof v === "object" && v !== null && "typeUrl" in v && !Array.isArray(v)) {
665
+ var any = v;
666
+ if (any.typeUrl === "")
667
+ return true;
668
+ }
669
+ return false;
670
+ }
671
+ // Cosmos textual "{TypeName} object" header uses the proto MESSAGE TYPE name,
672
+ // not the field name. Most of our fields coincidentally match (params→Params,
673
+ // plan→Plan, grant→Grant), but some don't (allow_list→Validators). Hardcode
674
+ // the known overrides; fallback to field-derived display name otherwise.
675
+ //
676
+ // Without this override, StakeAuthorization.allow_list rendered as "Allow list
677
+ // object" while the chain produced "Validators object", and every stake-grant
678
+ // tx failed TEXTUAL signature verification. Extend this map when a new
679
+ // field→type name divergence is discovered in a failing tx.
680
+ function getNestedMessageTypeName(fieldName, parentTypeUrl) {
681
+ if (parentTypeUrl === "/cosmos.staking.v1beta1.StakeAuthorization") {
682
+ if (fieldName === "allowList" || fieldName === "denyList")
683
+ return "Validators";
684
+ }
685
+ if (parentTypeUrl === "/cosmos.feegrant.v1beta1.PeriodicAllowance") {
686
+ // `basic` is a nested BasicAllowance message — chain renderer uses the
687
+ // proto type name "BasicAllowance" in the "{Type} object" header, not the
688
+ // field-derived "Basic".
689
+ if (fieldName === "basic")
690
+ return "BasicAllowance";
691
+ }
692
+ return fieldToDisplayName(fieldName, parentTypeUrl);
693
+ }
694
+ // Renders a nested proto message object as title+content header followed by sub-fields.
695
+ // Mirrors Cosmos SDK MessageValueRenderer: "{TypeName} object" header + sub-fields at indent+1.
696
+ function renderNestedProtoMessage(obj, fieldName, baseIndent, restUrl, screens, registry, parentTypeUrl) {
697
+ return __awaiter(this, void 0, void 0, function () {
698
+ var displayName, typeName;
699
+ return __generator(this, function (_a) {
700
+ switch (_a.label) {
701
+ case 0:
702
+ displayName = fieldToDisplayName(fieldName, parentTypeUrl);
703
+ typeName = getNestedMessageTypeName(fieldName, parentTypeUrl);
704
+ screens.push({ title: displayName, content: "".concat(typeName, " object"), indent: baseIndent });
705
+ return [4 /*yield*/, renderMessageFields(obj, baseIndent + 1, registry, restUrl, screens, parentTypeUrl)];
706
+ case 1:
707
+ _a.sent();
708
+ return [2 /*return*/];
709
+ }
710
+ });
711
+ });
712
+ }
713
+ // Dispatches a single field to the appropriate renderer (Any / repeated scalar /
714
+ // nested message / scalar fallback). Extracted from the three duplicated loops
715
+ // in renderSingleAnyField, renderNestedProtoMessage, and buildTextualScreens.
716
+ function renderSingleField(fieldName, value, baseIndent, registry, restUrl, screens, parentTypeUrl) {
717
+ return __awaiter(this, void 0, void 0, function () {
718
+ var content, e_4;
719
+ return __generator(this, function (_a) {
720
+ switch (_a.label) {
721
+ case 0:
722
+ if (!isSingleAnyObject(value)) return [3 /*break*/, 2];
723
+ return [4 /*yield*/, renderSingleAnyField(fieldName, value, baseIndent, registry, restUrl, screens, parentTypeUrl)];
724
+ case 1:
725
+ _a.sent();
726
+ return [2 /*return*/];
727
+ case 2:
728
+ if (!(Array.isArray(value) && isMultiScreenRepeated(value))) return [3 /*break*/, 4];
729
+ return [4 /*yield*/, renderRepeatedScalar(fieldName, value, baseIndent, restUrl, screens, parentTypeUrl)];
730
+ case 3:
731
+ _a.sent();
732
+ return [2 /*return*/];
733
+ case 4:
734
+ if (!isPlainProtoMessage(value)) return [3 /*break*/, 6];
735
+ return [4 /*yield*/, renderNestedProtoMessage(value, fieldName, baseIndent, restUrl, screens, registry, parentTypeUrl)];
736
+ case 5:
737
+ _a.sent();
738
+ return [2 /*return*/];
739
+ case 6:
740
+ _a.trys.push([6, 8, , 9]);
741
+ return [4 /*yield*/, renderFieldValue(value, restUrl, fieldName, parentTypeUrl)];
742
+ case 7:
743
+ content = _a.sent();
744
+ return [3 /*break*/, 9];
745
+ case 8:
746
+ e_4 = _a.sent();
747
+ console.warn('[Textual] renderFieldValue error for field', fieldName, ':', e_4);
748
+ content = "(error)";
749
+ return [3 /*break*/, 9];
750
+ case 9:
751
+ screens.push({ title: fieldToDisplayName(fieldName, parentTypeUrl), content: content, indent: baseIndent });
752
+ return [2 /*return*/];
753
+ }
754
+ });
755
+ });
756
+ }
757
+ // Iterates a proto message's fields, skipping proto3-default values and
758
+ // dispatching the rest through renderSingleField.
759
+ function renderMessageFields(fields, baseIndent, registry, restUrl, screens, parentTypeUrl) {
760
+ return __awaiter(this, void 0, void 0, function () {
761
+ var _a, _b, _c, k, v, e_5_1;
762
+ var e_5, _d;
763
+ return __generator(this, function (_e) {
764
+ switch (_e.label) {
765
+ case 0:
766
+ _e.trys.push([0, 5, 6, 7]);
767
+ _a = __values(Object.entries(fields)), _b = _a.next();
768
+ _e.label = 1;
769
+ case 1:
770
+ if (!!_b.done) return [3 /*break*/, 4];
771
+ _c = __read(_b.value, 2), k = _c[0], v = _c[1];
772
+ if (shouldSkipField(v))
773
+ return [3 /*break*/, 3];
774
+ return [4 /*yield*/, renderSingleField(k, v, baseIndent, registry, restUrl, screens, parentTypeUrl)];
775
+ case 2:
776
+ _e.sent();
777
+ _e.label = 3;
778
+ case 3:
779
+ _b = _a.next();
780
+ return [3 /*break*/, 1];
781
+ case 4: return [3 /*break*/, 7];
782
+ case 5:
783
+ e_5_1 = _e.sent();
784
+ e_5 = { error: e_5_1 };
785
+ return [3 /*break*/, 7];
786
+ case 6:
787
+ try {
788
+ if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
789
+ }
790
+ finally { if (e_5) throw e_5.error; }
791
+ return [7 /*endfinally*/];
792
+ case 7: return [2 /*return*/];
793
+ }
794
+ });
795
+ });
796
+ }
797
+ function renderFieldValue(value, restUrl, fieldName, typeUrl) {
798
+ var _a, _b;
799
+ return __awaiter(this, void 0, void 0, function () {
800
+ var tv, coin, meta;
801
+ return __generator(this, function (_c) {
802
+ switch (_c.label) {
803
+ case 0:
804
+ if (typeof value === "string") {
805
+ if (fieldName && COSMOS_DEC_FIELDS.has(fieldName))
806
+ return [2 /*return*/, renderCosmosDecString(value)];
807
+ return [2 /*return*/, value];
808
+ }
809
+ if (typeof value === "number" || typeof value === "bigint") {
810
+ // VoteOption enum → string name
811
+ if (typeUrl === "/cosmos.gov.v1.MsgVote" && fieldName === "option" && typeof value === "number") {
812
+ return [2 /*return*/, (_a = VOTE_OPTION_NAMES[value]) !== null && _a !== void 0 ? _a : String(value)];
813
+ }
814
+ // StakeAuthorization.AuthorizationType enum → string name
815
+ if (typeUrl === "/cosmos.staking.v1beta1.StakeAuthorization" && fieldName === "authorizationType" && typeof value === "number") {
816
+ return [2 /*return*/, (_b = STAKE_AUTHORIZATION_TYPE_NAMES[value]) !== null && _b !== void 0 ? _b : String(value)];
817
+ }
818
+ return [2 /*return*/, formatIntWithSep(value.toString())];
819
+ }
820
+ // Long.js object (protobufjs uint64/int64) → decimal string with apostrophe separators
821
+ if (isLongObject(value))
822
+ return [2 /*return*/, formatIntWithSep(value.toString())];
823
+ if (typeof value === "boolean")
824
+ return [2 /*return*/, value ? "True" : "False"];
825
+ if (value instanceof Uint8Array)
826
+ return [2 /*return*/, "(".concat(value.length, " bytes)")];
827
+ if (Array.isArray(value)) {
828
+ if (value.length === 0)
829
+ return [2 /*return*/, "(none)"];
830
+ if (typeof value[0] === "object" &&
831
+ value[0] !== null &&
832
+ "denom" in value[0] &&
833
+ "amount" in value[0]) {
834
+ return [2 /*return*/, formatCoins(value, restUrl)];
835
+ }
836
+ // Any[] — show typeUrls only to avoid Uint8Array serialization
837
+ if (typeof value[0] === "object" && value[0] !== null && "typeUrl" in value[0]) {
838
+ return [2 /*return*/, value.map(function (a) { return a.typeUrl; }).join(", ")];
839
+ }
840
+ return [2 /*return*/, JSON.stringify(value)];
841
+ }
842
+ if (!(typeof value === "object" && value !== null)) return [3 /*break*/, 3];
843
+ // proto Duration / Timestamp { seconds, nanos } — identical shape, disambiguated by field name
844
+ if ("seconds" in value) {
845
+ tv = value;
846
+ if (fieldName && TIMESTAMP_FIELD_NAMES.has(fieldName)) {
847
+ return [2 /*return*/, renderTimestamp(tv)];
848
+ }
849
+ return [2 /*return*/, renderDuration(tv)];
850
+ }
851
+ if (!("denom" in value && "amount" in value)) return [3 /*break*/, 2];
852
+ coin = value;
853
+ return [4 /*yield*/, queryCoinMetadata(restUrl, coin.denom)];
854
+ case 1:
855
+ meta = _c.sent();
856
+ return [2 /*return*/, formatOneCoin(coin.amount, coin.denom, meta)];
857
+ case 2:
858
+ // Any object — show typeUrl only
859
+ if ("typeUrl" in value)
860
+ return [2 /*return*/, value.typeUrl];
861
+ return [2 /*return*/, JSON.stringify(value)];
862
+ case 3: return [2 /*return*/, String(value !== null && value !== void 0 ? value : "")];
863
+ }
864
+ });
865
+ });
866
+ }
867
+ // ─── Amino signing (SIGN_MODE_LEGACY_AMINO_JSON) ──────────────────────────────
868
+ function signWithSignerAmino(signer, messages, signerData, option, registry) {
869
+ return __awaiter(this, void 0, void 0, function () {
870
+ var pubkey, pubkeyProto, aminoTypes, aminoMsgs, stdFee, signDoc, signStr, signature, anyMsgs, bodyBytes, feeCoins, authInfoBytes;
871
+ return __generator(this, function (_a) {
872
+ switch (_a.label) {
873
+ case 0: return [4 /*yield*/, signer.getPublicKey()];
874
+ case 1:
875
+ pubkey = _a.sent();
125
876
  pubkeyProto = {
126
877
  typeUrl: "/cosmos.crypto.secp256k1.PubKey",
127
878
  value: keys_1.PubKey.encode({ key: pubkey }).finish(),
128
879
  };
129
- feeAmount = option.fee.amount.map(function (a) { return ({
130
- denom: a.denom,
131
- amount: a.amount,
132
- }); });
133
- authInfoBytes = makeAuthInfoBytesDirect(pubkeyProto, feeAmount, option.fee.gasLimit, signerData.sequence);
134
- signDoc = tx_1.SignDoc.fromPartial({
135
- bodyBytes: bodyBytes,
136
- authInfoBytes: authInfoBytes,
137
- chainId: signerData.chain_id,
138
- accountNumber: BigInt(signerData.account_number),
139
- });
140
- // Verify SignDoc has all required fields
141
- if (!signDoc.chainId) {
142
- throw new Error("SignDoc chainId is missing: ".concat(signDoc.chainId));
143
- }
144
- if (!signDoc.accountNumber) {
145
- throw new Error("SignDoc accountNumber is missing: ".concat(signDoc.accountNumber));
146
- }
147
- signDocBytes = tx_1.SignDoc.encode(signDoc).finish();
148
- base64SignBytes = (0, encoding_1.toBase64)(signDocBytes);
149
- protobufAttempts = [
150
- { name: "SignDoc Base64", data: base64SignBytes },
151
- { name: "SignDoc Hex", data: Buffer.from(signDocBytes).toString('hex') },
152
- { name: "SignDoc Hex with 0x", data: '0x' + Buffer.from(signDocBytes).toString('hex') },
153
- ];
154
- _b.label = 2;
880
+ aminoTypes = buildAminoTypesForCheck();
881
+ aminoMsgs = messages.map(function (msg) { return aminoTypes.toAmino(msg); });
882
+ stdFee = {
883
+ amount: option.fee.amount.map(function (c) { return ({ denom: c.denom, amount: c.amount }); }),
884
+ gas: option.fee.gasLimit.toString(),
885
+ granter: option.fee.granter || undefined,
886
+ payer: option.fee.payer || undefined,
887
+ };
888
+ signDoc = (0, amino_1.makeSignDoc)(aminoMsgs, stdFee, signerData.chain_id, option.memo || "", signerData.account_number, signerData.sequence);
889
+ signStr = Buffer.from((0, amino_1.serializeSignDoc)(signDoc)).toString("utf8");
890
+ return [4 /*yield*/, signer.sign(signStr, 0x00)];
891
+ case 2:
892
+ signature = _a.sent();
893
+ if (!signature || signature.length === 0)
894
+ throw new Error("Signature is empty. Please confirm the transaction on your Ledger device.");
895
+ if (signature.length !== 64)
896
+ throw new Error("Unexpected signature length: ".concat(signature.length, " bytes (expected 64)"));
897
+ anyMsgs = messages.map(function (msg) { return registry.encodeAsAny(msg); });
898
+ bodyBytes = tx_1.TxBody.encode(tx_1.TxBody.fromPartial({ messages: anyMsgs, memo: option.memo || "" })).finish();
899
+ feeCoins = option.fee.amount.map(function (a) { return ({ denom: a.denom, amount: a.amount }); });
900
+ authInfoBytes = (0, signing_2.makeAuthInfoBytes)([{ pubkey: pubkeyProto, sequence: signerData.sequence }], feeCoins, option.fee.gasLimit, option.fee.granter || undefined, option.fee.payer || undefined, signing_1.SignMode.SIGN_MODE_LEGACY_AMINO_JSON);
901
+ return [2 /*return*/, tx_1.TxRaw.fromPartial({ bodyBytes: bodyBytes, authInfoBytes: authInfoBytes, signatures: [signature] })];
902
+ }
903
+ });
904
+ });
905
+ }
906
+ exports.signWithSignerAmino = signWithSignerAmino;
907
+ // ─── Textual signing (SIGN_MODE_TEXTUAL, P2=0x01) ─────────────────────────────
908
+ function buildTextualScreens(messages, signerData, option, pubkey, address, bodyBytes, authInfoBytes, restApiAddress, registry) {
909
+ return __awaiter(this, void 0, void 0, function () {
910
+ var screens, count, i, msg, fields, MsgType, encodedBytes, _a, _b, _c, k, v, anyArray, anyCount, fieldTitle, j, anyItem, decoder, valueBytes, nested, e_6, e_7_1, feeCoins, _d, _e;
911
+ var e_7, _f, _g;
912
+ return __generator(this, function (_h) {
913
+ switch (_h.label) {
914
+ case 0:
915
+ screens = [];
916
+ screens.push({ title: "Chain id", content: signerData.chain_id });
917
+ screens.push({ title: "Account number", content: signerData.account_number.toString() });
918
+ screens.push({ title: "Sequence", content: signerData.sequence.toString() });
919
+ screens.push({ title: "Address", content: address, expert: true });
920
+ screens.push({ title: "Public key", content: "/cosmos.crypto.secp256k1.PubKey", expert: true });
921
+ screens.push({ title: "Key", content: formatPubkeyHex(pubkey), indent: 1, expert: true });
922
+ count = messages.length;
923
+ screens.push({ content: "This transaction has ".concat(count, " Message").concat(count === 1 ? "" : "s") });
924
+ i = 0;
925
+ _h.label = 1;
926
+ case 1:
927
+ if (!(i < messages.length)) return [3 /*break*/, 19];
928
+ msg = messages[i];
929
+ screens.push({ title: "Message (".concat(i + 1, "/").concat(count, ")"), content: msg.typeUrl, indent: 1 });
930
+ fields = {};
931
+ MsgType = registry.lookupType(msg.typeUrl);
932
+ if (MsgType) {
933
+ try {
934
+ encodedBytes = registry.encodeAsAny(msg).value;
935
+ fields = MsgType.decode(encodedBytes);
936
+ }
937
+ catch (_j) {
938
+ if (msg.value && typeof msg.value === "object") {
939
+ fields = msg.value;
940
+ }
941
+ }
942
+ }
943
+ else if (msg.value && typeof msg.value === "object") {
944
+ fields = msg.value;
945
+ }
946
+ if (DEBUG_LEDGER)
947
+ console.log('[Textual] typeUrl:', msg.typeUrl, 'fields keys:', Object.keys(fields));
948
+ _h.label = 2;
155
949
  case 2:
156
- _b.trys.push([2, 9, 10, 11]);
157
- protobufAttempts_1 = __values(protobufAttempts), protobufAttempts_1_1 = protobufAttempts_1.next();
158
- _b.label = 3;
950
+ _h.trys.push([2, 16, 17, 18]);
951
+ _a = (e_7 = void 0, __values(Object.entries(fields))), _b = _a.next();
952
+ _h.label = 3;
159
953
  case 3:
160
- if (!!protobufAttempts_1_1.done) return [3 /*break*/, 8];
161
- attempt = protobufAttempts_1_1.value;
162
- _b.label = 4;
954
+ if (!!_b.done) return [3 /*break*/, 15];
955
+ _c = __read(_b.value, 2), k = _c[0], v = _c[1];
956
+ if (shouldSkipField(v))
957
+ return [3 /*break*/, 14];
958
+ if (!(Array.isArray(v) &&
959
+ v.length > 0 &&
960
+ typeof v[0] === "object" &&
961
+ v[0] !== null &&
962
+ "typeUrl" in v[0] &&
963
+ "value" in v[0] &&
964
+ toUint8ArraySafe(v[0].value) !== null)) return [3 /*break*/, 12];
965
+ anyArray = v;
966
+ anyCount = anyArray.length;
967
+ fieldTitle = fieldToDisplayName(k, msg.typeUrl);
968
+ // Header: "N Any" matches SDK's formatRepeated count screen (getKind = "Any" for google.protobuf.Any)
969
+ screens.push({ title: fieldTitle, content: "".concat(anyCount, " Any"), indent: 2 });
970
+ j = 0;
971
+ _h.label = 4;
163
972
  case 4:
164
- _b.trys.push([4, 6, , 7]);
165
- return [4 /*yield*/, signer.sign(attempt.data)];
973
+ if (!(j < anyArray.length)) return [3 /*break*/, 11];
974
+ anyItem = anyArray[j];
975
+ // Any renderer replaces "{Type} object" header with typeUrl — use typeUrl as content
976
+ screens.push({ title: "".concat(fieldTitle, " (").concat(j + 1, "/").concat(anyCount, ")"), content: anyItem.typeUrl, indent: 3 });
977
+ decoder = lookupNestedDecoder(anyItem.typeUrl, registry);
978
+ valueBytes = toUint8ArraySafe(anyItem.value);
979
+ if (!(decoder && valueBytes)) return [3 /*break*/, 9];
980
+ _h.label = 5;
166
981
  case 5:
167
- signature = _b.sent();
168
- if (signature && signature.length > 0) {
169
- return [3 /*break*/, 8]; // Success! Exit loop
170
- }
171
- return [3 /*break*/, 7];
982
+ _h.trys.push([5, 7, , 8]);
983
+ nested = decoder.decode(valueBytes);
984
+ return [4 /*yield*/, renderMessageFields(nested, 4, registry, restApiAddress, screens, anyItem.typeUrl)];
172
985
  case 6:
173
- signError_1 = _b.sent();
174
- lastError = signError_1;
175
- return [3 /*break*/, 7]; // Try next format
986
+ _h.sent();
987
+ return [3 /*break*/, 8];
176
988
  case 7:
177
- protobufAttempts_1_1 = protobufAttempts_1.next();
178
- return [3 /*break*/, 3];
179
- case 8: return [3 /*break*/, 11];
989
+ e_6 = _h.sent();
990
+ console.warn('[Textual] nested Any decode error for', anyItem.typeUrl, ':', e_6);
991
+ return [3 /*break*/, 8];
992
+ case 8: return [3 /*break*/, 10];
180
993
  case 9:
181
- e_1_1 = _b.sent();
182
- e_1 = { error: e_1_1 };
183
- return [3 /*break*/, 11];
994
+ console.warn('[Textual] no decoder for nested Any:', anyItem.typeUrl);
995
+ _h.label = 10;
184
996
  case 10:
997
+ j++;
998
+ return [3 /*break*/, 4];
999
+ case 11:
1000
+ // Terminal screen for repeated Any field (mirrors SDK formatRepeated terminalScreen)
1001
+ screens.push({ content: "End of ".concat(fieldTitle), indent: 2 });
1002
+ return [3 /*break*/, 14];
1003
+ case 12:
1004
+ // Non-Any[] fields: dispatch through the shared single-field renderer
1005
+ return [4 /*yield*/, renderSingleField(k, v, 2, registry, restApiAddress, screens, msg.typeUrl)];
1006
+ case 13:
1007
+ // Non-Any[] fields: dispatch through the shared single-field renderer
1008
+ _h.sent();
1009
+ _h.label = 14;
1010
+ case 14:
1011
+ _b = _a.next();
1012
+ return [3 /*break*/, 3];
1013
+ case 15: return [3 /*break*/, 18];
1014
+ case 16:
1015
+ e_7_1 = _h.sent();
1016
+ e_7 = { error: e_7_1 };
1017
+ return [3 /*break*/, 18];
1018
+ case 17:
185
1019
  try {
186
- if (protobufAttempts_1_1 && !protobufAttempts_1_1.done && (_a = protobufAttempts_1.return)) _a.call(protobufAttempts_1);
1020
+ if (_b && !_b.done && (_f = _a.return)) _f.call(_a);
187
1021
  }
188
- finally { if (e_1) throw e_1.error; }
1022
+ finally { if (e_7) throw e_7.error; }
189
1023
  return [7 /*endfinally*/];
190
- case 11:
191
- // If all Protobuf attempts failed, provide guidance
192
- if (!signature || signature.length === 0) {
193
- errorMsg = lastError instanceof Error ? lastError.message : String(lastError);
194
- throw new Error("FirmaChain Ledger app signing failed: ".concat(errorMsg, ". Please ensure FirmaChain app is properly installed and up to date."));
195
- }
196
- // Signature validation
197
- if (!signature || signature.length === 0) {
198
- throw new Error("Signature is empty. Please confirm that the transaction was approved on Ledger or check Ledger connection.");
199
- }
200
- if (signature.length !== 64) {
201
- throw new Error("Unexpected signature length: ".concat(signature.length, " bytes (expected: 64 bytes)"));
202
- }
203
- txRaw = tx_1.TxRaw.fromPartial({
204
- bodyBytes: bodyBytes,
205
- authInfoBytes: authInfoBytes,
206
- signatures: [signature],
1024
+ case 18:
1025
+ i++;
1026
+ return [3 /*break*/, 1];
1027
+ case 19:
1028
+ // One "End of Message" terminal after all messages (SDK formatRepeated terminal for Envelope.message field)
1029
+ screens.push({ content: "End of Message" });
1030
+ // Memo — chain's envelope renderer emits this iff memo != "" (proto3 default skipped).
1031
+ // Must sit between "End of Message" and "Fees"; otherwise CBOR diverges from the chain's.
1032
+ if (option.memo && option.memo.length > 0) {
1033
+ screens.push({ title: "Memo", content: option.memo });
1034
+ }
1035
+ feeCoins = option.fee.amount.map(function (c) { return ({ denom: c.denom, amount: c.amount }); });
1036
+ _e = (_d = screens).push;
1037
+ _g = { title: "Fees" };
1038
+ return [4 /*yield*/, formatCoins(feeCoins, restApiAddress)];
1039
+ case 20:
1040
+ _e.apply(_d, [(_g.content = _h.sent(), _g)]);
1041
+ // Fee payer / Fee granter — conditional, non-expert, emitted by chain's renderFee.
1042
+ if (option.fee.payer) {
1043
+ screens.push({ title: "Fee payer", content: option.fee.payer });
1044
+ }
1045
+ if (option.fee.granter) {
1046
+ screens.push({ title: "Fee granter", content: option.fee.granter });
1047
+ }
1048
+ screens.push({ title: "Gas limit", content: formatGasLimit(option.fee.gasLimit), expert: true });
1049
+ screens.push({
1050
+ title: "Hash of raw bytes",
1051
+ content: computeRawBytesHash(bodyBytes, authInfoBytes),
1052
+ expert: true,
207
1053
  });
208
- return [2 /*return*/, txRaw];
1054
+ return [2 /*return*/, screens];
1055
+ }
1056
+ });
1057
+ });
1058
+ }
1059
+ // ─── Auto sign mode routing ───────────────────────────────────────────────────
1060
+ function buildAminoTypesForCheck() {
1061
+ var baseConverters = __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({}, (0, stargate_1.createBankAminoConverters)()), (0, stargate_1.createStakingAminoConverters)()), (0, stargate_1.createDistributionAminoConverters)()), (0, stargate_1.createGovAminoConverters)()), (0, stargate_1.createIbcAminoConverters)()), (0, stargate_1.createFeegrantAminoConverters)()), (0, stargate_1.createAuthzAminoConverters)()), (0, stargate_1.createVestingAminoConverters)());
1062
+ // Custom converters for nested governance action messages absent from @cosmjs/stargate 0.34.x
1063
+ var nestedMsgConverters = {
1064
+ "/cosmos.distribution.v1beta1.MsgCommunityPoolSpend": {
1065
+ aminoType: "cosmos-sdk/distr/MsgCommunityPoolSpend",
1066
+ toAmino: function (value) { return ({
1067
+ authority: value.authority,
1068
+ recipient: value.recipient,
1069
+ amount: value.amount,
1070
+ }); },
1071
+ fromAmino: function (value) { return ({
1072
+ authority: value.authority,
1073
+ recipient: value.recipient,
1074
+ amount: value.amount,
1075
+ }); },
1076
+ },
1077
+ "/cosmos.staking.v1beta1.MsgUpdateParams": {
1078
+ aminoType: "cosmos-sdk/x/staking/MsgUpdateParams",
1079
+ toAmino: function (value) {
1080
+ var _a, _b;
1081
+ var p = (_a = value.params) !== null && _a !== void 0 ? _a : {};
1082
+ return {
1083
+ authority: value.authority,
1084
+ params: {
1085
+ unbonding_time: p.unbondingTime ? durationToAminoNanos(p.unbondingTime) : "0",
1086
+ max_validators: p.maxValidators,
1087
+ max_entries: p.maxEntries,
1088
+ historical_entries: p.historicalEntries,
1089
+ bond_denom: p.bondDenom,
1090
+ min_commission_rate: (_b = p.minCommissionRate) !== null && _b !== void 0 ? _b : "0",
1091
+ },
1092
+ };
1093
+ },
1094
+ fromAmino: function (value) { return value; },
1095
+ },
1096
+ "/cosmos.gov.v1.MsgUpdateParams": {
1097
+ aminoType: "cosmos-sdk/x/gov/v1/MsgUpdateParams",
1098
+ toAmino: function (value) {
1099
+ var _a, _b, _c, _d, _e, _f;
1100
+ var p = (_a = value.params) !== null && _a !== void 0 ? _a : {};
1101
+ var result = {
1102
+ authority: value.authority,
1103
+ params: __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({}, (((_b = p.minDeposit) === null || _b === void 0 ? void 0 : _b.length) ? { min_deposit: p.minDeposit } : {})), (p.maxDepositPeriod ? { max_deposit_period: durationToAminoNanos(p.maxDepositPeriod) } : {})), (p.votingPeriod ? { voting_period: durationToAminoNanos(p.votingPeriod) } : {})), (p.quorum ? { quorum: p.quorum } : {})), (p.threshold ? { threshold: p.threshold } : {})), (p.vetoThreshold ? { veto_threshold: p.vetoThreshold } : {})), (p.minInitialDepositRatio ? { min_initial_deposit_ratio: p.minInitialDepositRatio } : {})), (p.proposalCancelRatio ? { proposal_cancel_ratio: p.proposalCancelRatio } : {})), (p.proposalCancelDest ? { proposal_cancel_dest: p.proposalCancelDest } : {})), (p.expeditedVotingPeriod ? { expedited_voting_period: durationToAminoNanos(p.expeditedVotingPeriod) } : {})), (p.expeditedThreshold ? { expedited_threshold: p.expeditedThreshold } : {})), (((_c = p.expeditedMinDeposit) === null || _c === void 0 ? void 0 : _c.length) ? { expedited_min_deposit: p.expeditedMinDeposit } : {})), { burn_vote_quorum: (_d = p.burnVoteQuorum) !== null && _d !== void 0 ? _d : false, burn_proposal_deposit_prevote: (_e = p.burnProposalDepositPrevote) !== null && _e !== void 0 ? _e : false, burn_vote_veto: (_f = p.burnVoteVeto) !== null && _f !== void 0 ? _f : false }), (p.minDepositRatio ? { min_deposit_ratio: p.minDepositRatio } : {})),
1104
+ };
1105
+ return result;
1106
+ },
1107
+ fromAmino: function (value) { return value; },
1108
+ },
1109
+ "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade": {
1110
+ aminoType: "cosmos-sdk/MsgSoftwareUpgrade",
1111
+ toAmino: function (value) {
1112
+ var _a, _b, _c, _d;
1113
+ var plan = (_a = value.plan) !== null && _a !== void 0 ? _a : {};
1114
+ return {
1115
+ authority: value.authority,
1116
+ plan: {
1117
+ name: plan.name,
1118
+ height: (_c = (_b = plan.height) === null || _b === void 0 ? void 0 : _b.toString()) !== null && _c !== void 0 ? _c : "0",
1119
+ info: (_d = plan.info) !== null && _d !== void 0 ? _d : "",
1120
+ },
1121
+ };
1122
+ },
1123
+ fromAmino: function (value) { return value; },
1124
+ },
1125
+ };
1126
+ // Build base amino types (with nested msg converters) for use inside the MsgSubmitProposal toAmino
1127
+ var baseAminoTypes = new stargate_1.AminoTypes(__assign(__assign({}, baseConverters), nestedMsgConverters));
1128
+ // All cosmos.gov.v1 messages are absent from @cosmjs/stargate 0.34.x createGovAminoConverters
1129
+ // (only v1beta1 is present). Without these converters signWithSignerAuto falls back to
1130
+ // SIGN_MODE_TEXTUAL, which the chain cannot verify.
1131
+ var govV1Converters = {
1132
+ "/cosmos.gov.v1.MsgSubmitProposal": {
1133
+ aminoType: "cosmos-sdk/v1/MsgSubmitProposal",
1134
+ toAmino: function (value) {
1135
+ var e_8, _a;
1136
+ var aminoMessages = [];
1137
+ try {
1138
+ for (var _b = __values((value.messages || [])), _c = _b.next(); !_c.done; _c = _b.next()) {
1139
+ var anyMsg = _c.value;
1140
+ var valueBytes = toUint8ArraySafe(anyMsg.value);
1141
+ var decoder = NESTED_ANY_DECODERS.get(anyMsg.typeUrl);
1142
+ if (decoder && valueBytes) {
1143
+ var decoded = decoder.decode(valueBytes);
1144
+ aminoMessages.push(baseAminoTypes.toAmino({ typeUrl: anyMsg.typeUrl, value: decoded }));
1145
+ }
1146
+ else {
1147
+ try {
1148
+ aminoMessages.push(baseAminoTypes.toAmino(anyMsg));
1149
+ }
1150
+ catch (_d) {
1151
+ throw new Error("Cannot amino-convert nested message: ".concat(anyMsg.typeUrl));
1152
+ }
1153
+ }
1154
+ }
1155
+ }
1156
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
1157
+ finally {
1158
+ try {
1159
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1160
+ }
1161
+ finally { if (e_8) throw e_8.error; }
1162
+ }
1163
+ var result = {
1164
+ proposer: value.proposer,
1165
+ title: value.title || "",
1166
+ summary: value.summary || "",
1167
+ };
1168
+ if (aminoMessages.length > 0)
1169
+ result.messages = aminoMessages;
1170
+ if (value.initialDeposit && value.initialDeposit.length > 0)
1171
+ result.initial_deposit = value.initialDeposit;
1172
+ if (value.metadata)
1173
+ result.metadata = value.metadata;
1174
+ if (value.expedited)
1175
+ result.expedited = value.expedited;
1176
+ return result;
1177
+ },
1178
+ fromAmino: function (value) {
1179
+ var _a, _b, _c, _d;
1180
+ return ({
1181
+ messages: (_a = value.messages) !== null && _a !== void 0 ? _a : [],
1182
+ initialDeposit: (_b = value.initial_deposit) !== null && _b !== void 0 ? _b : [],
1183
+ proposer: value.proposer,
1184
+ title: value.title,
1185
+ summary: value.summary,
1186
+ metadata: (_c = value.metadata) !== null && _c !== void 0 ? _c : "",
1187
+ expedited: (_d = value.expedited) !== null && _d !== void 0 ? _d : false,
1188
+ });
1189
+ },
1190
+ },
1191
+ "/cosmos.gov.v1.MsgVote": {
1192
+ aminoType: "cosmos-sdk/v1/MsgVote",
1193
+ toAmino: function (value) {
1194
+ var result = {
1195
+ proposal_id: value.proposalId.toString(),
1196
+ voter: value.voter,
1197
+ option: value.option,
1198
+ };
1199
+ if (value.metadata)
1200
+ result.metadata = value.metadata;
1201
+ return result;
1202
+ },
1203
+ fromAmino: function (value) {
1204
+ var _a;
1205
+ return ({
1206
+ proposalId: BigInt(value.proposal_id),
1207
+ voter: value.voter,
1208
+ option: value.option,
1209
+ metadata: (_a = value.metadata) !== null && _a !== void 0 ? _a : "",
1210
+ });
1211
+ },
1212
+ },
1213
+ "/cosmos.gov.v1.MsgVoteWeighted": {
1214
+ aminoType: "cosmos-sdk/v1/MsgVoteWeighted",
1215
+ toAmino: function (value) {
1216
+ var result = {
1217
+ proposal_id: value.proposalId.toString(),
1218
+ voter: value.voter,
1219
+ options: value.options,
1220
+ };
1221
+ if (value.metadata)
1222
+ result.metadata = value.metadata;
1223
+ return result;
1224
+ },
1225
+ fromAmino: function (value) {
1226
+ var _a;
1227
+ return ({
1228
+ proposalId: BigInt(value.proposal_id),
1229
+ voter: value.voter,
1230
+ options: value.options,
1231
+ metadata: (_a = value.metadata) !== null && _a !== void 0 ? _a : "",
1232
+ });
1233
+ },
1234
+ },
1235
+ "/cosmos.gov.v1.MsgDeposit": {
1236
+ aminoType: "cosmos-sdk/v1/MsgDeposit",
1237
+ toAmino: function (value) { return ({
1238
+ proposal_id: value.proposalId.toString(),
1239
+ depositor: value.depositor,
1240
+ amount: value.amount,
1241
+ }); },
1242
+ fromAmino: function (value) { return ({
1243
+ proposalId: BigInt(value.proposal_id),
1244
+ depositor: value.depositor,
1245
+ amount: value.amount,
1246
+ }); },
1247
+ },
1248
+ "/cosmos.gov.v1.MsgCancelProposal": {
1249
+ aminoType: "cosmos-sdk/v1/MsgCancelProposal",
1250
+ toAmino: function (value) { return ({
1251
+ proposal_id: value.proposalId.toString(),
1252
+ proposer: value.proposer,
1253
+ }); },
1254
+ fromAmino: function (value) { return ({
1255
+ proposalId: BigInt(value.proposal_id),
1256
+ proposer: value.proposer,
1257
+ }); },
1258
+ },
1259
+ };
1260
+ return new stargate_1.AminoTypes(__assign(__assign(__assign({}, baseConverters), nestedMsgConverters), govV1Converters));
1261
+ }
1262
+ function signWithSignerAuto(signer, messages, signerData, option, registry, restApiAddress, simulate) {
1263
+ if (restApiAddress === void 0) { restApiAddress = ""; }
1264
+ if (simulate === void 0) { simulate = false; }
1265
+ return __awaiter(this, void 0, void 0, function () {
1266
+ var typeUrls;
1267
+ return __generator(this, function (_a) {
1268
+ if (simulate) {
1269
+ return [2 /*return*/, buildSimulationTxRawLedger(signer, messages, signerData, option, registry)];
1270
+ }
1271
+ if (DEBUG_LEDGER) {
1272
+ typeUrls = messages.map(function (m) { return m.typeUrl; }).join(', ');
1273
+ console.log("[Ledger] sign mode: TEXTUAL | msgs: ".concat(typeUrls));
1274
+ }
1275
+ return [2 /*return*/, signWithSignerTextual(signer, messages, signerData, option, registry, restApiAddress)];
1276
+ });
1277
+ });
1278
+ }
1279
+ exports.signWithSignerAuto = signWithSignerAuto;
1280
+ // Builds an unsigned TxRaw for simulation (gas estimation) without prompting the
1281
+ // Ledger device. Uses a 64-byte zero signature; the chain skips signature
1282
+ // verification in `runTxModeSimulate`, so the simulated gas is still accurate.
1283
+ function buildSimulationTxRawLedger(signer, messages, signerData, option, registry) {
1284
+ return __awaiter(this, void 0, void 0, function () {
1285
+ var pubkey, pubkeyProto, anyMsgs, bodyBytes, feeCoins, authInfoBytes;
1286
+ return __generator(this, function (_a) {
1287
+ switch (_a.label) {
1288
+ case 0: return [4 /*yield*/, signer.getAddressAndPublicKey()];
1289
+ case 1:
1290
+ pubkey = (_a.sent()).publicKey;
1291
+ pubkeyProto = {
1292
+ typeUrl: "/cosmos.crypto.secp256k1.PubKey",
1293
+ value: keys_1.PubKey.encode({ key: pubkey }).finish(),
1294
+ };
1295
+ anyMsgs = messages.map(function (msg) { return registry.encodeAsAny(msg); });
1296
+ bodyBytes = tx_1.TxBody.encode(tx_1.TxBody.fromPartial({ messages: anyMsgs, memo: option.memo || "" })).finish();
1297
+ feeCoins = option.fee.amount.map(function (a) { return ({ denom: a.denom, amount: a.amount }); });
1298
+ authInfoBytes = (0, signing_2.makeAuthInfoBytes)([{ pubkey: pubkeyProto, sequence: signerData.sequence }], feeCoins, option.fee.gasLimit, option.fee.granter || undefined, option.fee.payer || undefined, signing_1.SignMode.SIGN_MODE_DIRECT);
1299
+ return [2 /*return*/, tx_1.TxRaw.fromPartial({ bodyBytes: bodyBytes, authInfoBytes: authInfoBytes, signatures: [new Uint8Array(64)] })];
1300
+ }
1301
+ });
1302
+ });
1303
+ }
1304
+ exports.buildSimulationTxRawLedger = buildSimulationTxRawLedger;
1305
+ function signWithSignerTextual(signer, messages, signerData, option, registry, restApiAddress) {
1306
+ if (restApiAddress === void 0) { restApiAddress = ""; }
1307
+ return __awaiter(this, void 0, void 0, function () {
1308
+ var _a, address, pubkey, pubkeyProto, anyMsgs, bodyBytes, feeCoins, authInfoBytes, screens, cborBuffer, signature;
1309
+ return __generator(this, function (_b) {
1310
+ switch (_b.label) {
1311
+ case 0: return [4 /*yield*/, signer.getAddressAndPublicKey()];
1312
+ case 1:
1313
+ _a = _b.sent(), address = _a.address, pubkey = _a.publicKey;
1314
+ pubkeyProto = {
1315
+ typeUrl: "/cosmos.crypto.secp256k1.PubKey",
1316
+ value: keys_1.PubKey.encode({ key: pubkey }).finish(),
1317
+ };
1318
+ anyMsgs = messages.map(function (msg) { return registry.encodeAsAny(msg); });
1319
+ bodyBytes = tx_1.TxBody.encode(tx_1.TxBody.fromPartial({ messages: anyMsgs, memo: option.memo || "" })).finish();
1320
+ feeCoins = option.fee.amount.map(function (a) { return ({ denom: a.denom, amount: a.amount }); });
1321
+ authInfoBytes = (0, signing_2.makeAuthInfoBytes)([{ pubkey: pubkeyProto, sequence: signerData.sequence }], feeCoins, option.fee.gasLimit, option.fee.granter || undefined, option.fee.payer || undefined, signing_1.SignMode.SIGN_MODE_TEXTUAL);
1322
+ return [4 /*yield*/, buildTextualScreens(messages, signerData, option, pubkey, address, bodyBytes, authInfoBytes, restApiAddress, registry)];
1323
+ case 2:
1324
+ screens = _b.sent();
1325
+ if (DEBUG_LEDGER_CBOR) {
1326
+ console.log('[Textual] === SCREENS DUMP ===');
1327
+ screens.forEach(function (s, i) {
1328
+ var parts = ["[".concat(i, "]")];
1329
+ if (s.title)
1330
+ parts.push("title=\"".concat(s.title, "\""));
1331
+ parts.push("content=\"".concat(s.content, "\""));
1332
+ if (s.indent)
1333
+ parts.push("indent=".concat(s.indent));
1334
+ if (s.expert)
1335
+ parts.push("expert=true");
1336
+ console.log('[Textual]', parts.join(' '));
1337
+ });
1338
+ }
1339
+ cborBuffer = encodeTextualCbor(screens);
1340
+ if (DEBUG_LEDGER_CBOR) {
1341
+ console.log('[Textual] CBOR hex:', Array.from(cborBuffer).map(function (b) { return b.toString(16).padStart(2, '0'); }).join(''));
1342
+ }
1343
+ return [4 /*yield*/, signer.sign(cborBuffer, 0x01)];
1344
+ case 3:
1345
+ signature = _b.sent();
1346
+ if (!signature || signature.length === 0)
1347
+ throw new Error("Signature is empty. Please confirm the transaction on your Ledger device.");
1348
+ if (signature.length !== 64)
1349
+ throw new Error("Unexpected signature length: ".concat(signature.length, " bytes (expected 64)"));
1350
+ return [2 /*return*/, tx_1.TxRaw.fromPartial({ bodyBytes: bodyBytes, authInfoBytes: authInfoBytes, signatures: [signature] })];
209
1351
  }
210
1352
  });
211
1353
  });
212
1354
  }
213
- exports.signWithSignerProtobuf = signWithSignerProtobuf;
1355
+ exports.signWithSignerTextual = signWithSignerTextual;