quais 1.0.0-alpha → 1.0.0-alpha.1

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 (134) hide show
  1. package/dist/quais.js +428 -73
  2. package/dist/quais.js.map +1 -1
  3. package/dist/quais.min.js +1 -1
  4. package/dist/quais.umd.js +428 -72
  5. package/dist/quais.umd.js.map +1 -1
  6. package/dist/quais.umd.min.js +1 -1
  7. package/lib/commonjs/constants/coins.d.ts +1 -2
  8. package/lib/commonjs/constants/coins.d.ts.map +1 -1
  9. package/lib/commonjs/constants/coins.js +0 -8
  10. package/lib/commonjs/constants/coins.js.map +1 -1
  11. package/lib/commonjs/constants/index.d.ts +1 -1
  12. package/lib/commonjs/constants/index.d.ts.map +1 -1
  13. package/lib/commonjs/constants/index.js +1 -4
  14. package/lib/commonjs/constants/index.js.map +1 -1
  15. package/lib/commonjs/contract/contract.d.ts.map +1 -1
  16. package/lib/commonjs/contract/contract.js +5 -11
  17. package/lib/commonjs/contract/contract.js.map +1 -1
  18. package/lib/commonjs/contract/factory.d.ts +1 -1
  19. package/lib/commonjs/contract/factory.d.ts.map +1 -1
  20. package/lib/commonjs/contract/factory.js.map +1 -1
  21. package/lib/commonjs/providers/index.d.ts +1 -1
  22. package/lib/commonjs/providers/index.d.ts.map +1 -1
  23. package/lib/commonjs/providers/index.js +2 -1
  24. package/lib/commonjs/providers/index.js.map +1 -1
  25. package/lib/commonjs/providers/provider-browser.d.ts +5 -3
  26. package/lib/commonjs/providers/provider-browser.d.ts.map +1 -1
  27. package/lib/commonjs/providers/provider-browser.js +28 -0
  28. package/lib/commonjs/providers/provider-browser.js.map +1 -1
  29. package/lib/commonjs/providers/provider-jsonrpc.d.ts +19 -1
  30. package/lib/commonjs/providers/provider-jsonrpc.d.ts.map +1 -1
  31. package/lib/commonjs/providers/provider-jsonrpc.js +261 -30
  32. package/lib/commonjs/providers/provider-jsonrpc.js.map +1 -1
  33. package/lib/commonjs/providers/provider.d.ts.map +1 -1
  34. package/lib/commonjs/providers/provider.js +4 -1
  35. package/lib/commonjs/providers/provider.js.map +1 -1
  36. package/lib/commonjs/quais.d.ts +1 -1
  37. package/lib/commonjs/quais.d.ts.map +1 -1
  38. package/lib/commonjs/quais.js +4 -3
  39. package/lib/commonjs/quais.js.map +1 -1
  40. package/lib/commonjs/signers/abstract-signer.d.ts +2 -3
  41. package/lib/commonjs/signers/abstract-signer.d.ts.map +1 -1
  42. package/lib/commonjs/signers/abstract-signer.js +4 -23
  43. package/lib/commonjs/signers/abstract-signer.js.map +1 -1
  44. package/lib/commonjs/transaction/quai-transaction.d.ts +3 -3
  45. package/lib/commonjs/transaction/quai-transaction.d.ts.map +1 -1
  46. package/lib/commonjs/transaction/quai-transaction.js +7 -4
  47. package/lib/commonjs/transaction/quai-transaction.js.map +1 -1
  48. package/lib/commonjs/wallet/base-wallet.d.ts.map +1 -1
  49. package/lib/commonjs/wallet/base-wallet.js +6 -6
  50. package/lib/commonjs/wallet/base-wallet.js.map +1 -1
  51. package/lib/commonjs/wallet/hdwallet.d.ts +22 -6
  52. package/lib/commonjs/wallet/hdwallet.d.ts.map +1 -1
  53. package/lib/commonjs/wallet/hdwallet.js +81 -11
  54. package/lib/commonjs/wallet/hdwallet.js.map +1 -1
  55. package/lib/commonjs/wallet/qi-hdwallet.d.ts +13 -3
  56. package/lib/commonjs/wallet/qi-hdwallet.d.ts.map +1 -1
  57. package/lib/commonjs/wallet/qi-hdwallet.js +58 -2
  58. package/lib/commonjs/wallet/qi-hdwallet.js.map +1 -1
  59. package/lib/commonjs/wallet/quai-hdwallet.d.ts +5 -3
  60. package/lib/commonjs/wallet/quai-hdwallet.d.ts.map +1 -1
  61. package/lib/commonjs/wallet/quai-hdwallet.js +10 -18
  62. package/lib/commonjs/wallet/quai-hdwallet.js.map +1 -1
  63. package/lib/esm/constants/coins.d.ts +1 -2
  64. package/lib/esm/constants/coins.d.ts.map +1 -1
  65. package/lib/esm/constants/coins.js +1 -7
  66. package/lib/esm/constants/coins.js.map +1 -1
  67. package/lib/esm/constants/index.d.ts +1 -1
  68. package/lib/esm/constants/index.d.ts.map +1 -1
  69. package/lib/esm/constants/index.js +0 -1
  70. package/lib/esm/constants/index.js.map +1 -1
  71. package/lib/esm/contract/contract.d.ts.map +1 -1
  72. package/lib/esm/contract/contract.js +5 -11
  73. package/lib/esm/contract/contract.js.map +1 -1
  74. package/lib/esm/contract/factory.d.ts +1 -1
  75. package/lib/esm/contract/factory.d.ts.map +1 -1
  76. package/lib/esm/contract/factory.js.map +1 -1
  77. package/lib/esm/providers/index.d.ts +1 -1
  78. package/lib/esm/providers/index.d.ts.map +1 -1
  79. package/lib/esm/providers/index.js +1 -1
  80. package/lib/esm/providers/index.js.map +1 -1
  81. package/lib/esm/providers/provider-browser.d.ts +5 -3
  82. package/lib/esm/providers/provider-browser.d.ts.map +1 -1
  83. package/lib/esm/providers/provider-browser.js +28 -0
  84. package/lib/esm/providers/provider-browser.js.map +1 -1
  85. package/lib/esm/providers/provider-jsonrpc.d.ts +19 -1
  86. package/lib/esm/providers/provider-jsonrpc.d.ts.map +1 -1
  87. package/lib/esm/providers/provider-jsonrpc.js +231 -1
  88. package/lib/esm/providers/provider-jsonrpc.js.map +1 -1
  89. package/lib/esm/providers/provider.d.ts.map +1 -1
  90. package/lib/esm/providers/provider.js +4 -1
  91. package/lib/esm/providers/provider.js.map +1 -1
  92. package/lib/esm/quais.d.ts +1 -1
  93. package/lib/esm/quais.d.ts.map +1 -1
  94. package/lib/esm/quais.js +1 -1
  95. package/lib/esm/quais.js.map +1 -1
  96. package/lib/esm/signers/abstract-signer.d.ts +2 -3
  97. package/lib/esm/signers/abstract-signer.d.ts.map +1 -1
  98. package/lib/esm/signers/abstract-signer.js +7 -26
  99. package/lib/esm/signers/abstract-signer.js.map +1 -1
  100. package/lib/esm/transaction/quai-transaction.d.ts +3 -3
  101. package/lib/esm/transaction/quai-transaction.d.ts.map +1 -1
  102. package/lib/esm/transaction/quai-transaction.js +7 -4
  103. package/lib/esm/transaction/quai-transaction.js.map +1 -1
  104. package/lib/esm/wallet/base-wallet.d.ts.map +1 -1
  105. package/lib/esm/wallet/base-wallet.js +6 -6
  106. package/lib/esm/wallet/base-wallet.js.map +1 -1
  107. package/lib/esm/wallet/hdwallet.d.ts +22 -6
  108. package/lib/esm/wallet/hdwallet.d.ts.map +1 -1
  109. package/lib/esm/wallet/hdwallet.js +84 -14
  110. package/lib/esm/wallet/hdwallet.js.map +1 -1
  111. package/lib/esm/wallet/qi-hdwallet.d.ts +13 -3
  112. package/lib/esm/wallet/qi-hdwallet.d.ts.map +1 -1
  113. package/lib/esm/wallet/qi-hdwallet.js +58 -2
  114. package/lib/esm/wallet/qi-hdwallet.js.map +1 -1
  115. package/lib/esm/wallet/quai-hdwallet.d.ts +5 -3
  116. package/lib/esm/wallet/quai-hdwallet.d.ts.map +1 -1
  117. package/lib/esm/wallet/quai-hdwallet.js +9 -17
  118. package/lib/esm/wallet/quai-hdwallet.js.map +1 -1
  119. package/package.json +2 -2
  120. package/src/constants/coins.ts +1 -3
  121. package/src/constants/index.ts +1 -1
  122. package/src/contract/contract.ts +5 -15
  123. package/src/contract/factory.ts +2 -1
  124. package/src/providers/index.ts +2 -9
  125. package/src/providers/provider-browser.ts +36 -5
  126. package/src/providers/provider-jsonrpc.ts +309 -2
  127. package/src/providers/provider.ts +4 -1
  128. package/src/quais.ts +1 -0
  129. package/src/signers/abstract-signer.ts +7 -34
  130. package/src/transaction/quai-transaction.ts +15 -7
  131. package/src/wallet/base-wallet.ts +9 -10
  132. package/src/wallet/hdwallet.ts +206 -71
  133. package/src/wallet/qi-hdwallet.ts +218 -146
  134. package/src/wallet/quai-hdwallet.ts +15 -22
package/dist/quais.js CHANGED
@@ -18926,7 +18926,10 @@ class QuaiTransaction extends AbstractTransaction {
18926
18926
  if (!this.originZone) {
18927
18927
  throw new Error('Invalid Zone for from address');
18928
18928
  }
18929
- const isSameLedger = isQiAddress(this.from) === isQiAddress(this.to || '');
18929
+ if (!(this.from && this.to)) {
18930
+ throw new Error('Missing from or to address');
18931
+ }
18932
+ const isSameLedger = isQiAddress(this.from) === isQiAddress(this.to);
18930
18933
  if (this.isExternal && !isSameLedger) {
18931
18934
  throw new Error('Cross-zone & cross-ledger transactions are not supported');
18932
18935
  }
@@ -18945,7 +18948,7 @@ class QuaiTransaction extends AbstractTransaction {
18945
18948
  * The zone of the sender address
18946
18949
  */
18947
18950
  get originZone() {
18948
- const zone = getZoneForAddress(this.from);
18951
+ const zone = this.from ? getZoneForAddress(this.from) : undefined;
18949
18952
  return zone ?? undefined;
18950
18953
  }
18951
18954
  /**
@@ -19195,8 +19198,8 @@ class QuaiTransaction extends AbstractTransaction {
19195
19198
  assertArgument(result.isSigned(), 'unsigned transaction cannot define hash', 'tx', tx);
19196
19199
  }
19197
19200
  if (tx.from != null) {
19198
- validateAddress(tx.from);
19199
- assertArgument(result.from.toLowerCase() === (tx.from || '').toLowerCase(), 'from mismatch', 'tx', tx);
19201
+ assertArgument(!isQiAddress(tx.from), 'from address must be a Quai address', 'tx.from', tx.from);
19202
+ assertArgument((result.from || '').toLowerCase() === (tx.from || '').toLowerCase(), 'from mismatch', 'tx', tx);
19200
19203
  result.from = tx.from;
19201
19204
  }
19202
19205
  return result;
@@ -19327,7 +19330,10 @@ function addressFromTransactionRequest(tx) {
19327
19330
  if (tx.inputs) {
19328
19331
  return getAddress(keccak256('0x' + SigningKey.computePublicKey(tx.inputs[0].pub_key).substring(4)).substring(26));
19329
19332
  }
19330
- throw new Error('Unable to determine sender from transaction inputs or from field');
19333
+ if ('to' in tx && tx.to !== null) {
19334
+ return tx.to;
19335
+ }
19336
+ throw new Error('Unable to determine address from transaction inputs, from or to field');
19331
19337
  }
19332
19338
  /**
19333
19339
  * Returns a copy of `req` with all properties coerced to their strict types.
@@ -21274,7 +21280,7 @@ function buildWrappedMethod(contract, key) {
21274
21280
  const resolvedArgs = await resolveArgs(contract.runner, fragment.inputs, args);
21275
21281
  return await resolveProperties({
21276
21282
  to: contract.getAddress(),
21277
- from: args.pop()?.from ?? '0x0000000000000000000000000000000000000000',
21283
+ from: args.pop()?.from,
21278
21284
  data: contract.interface.encodeFunctionData(fragment, resolvedArgs),
21279
21285
  });
21280
21286
  };
@@ -21291,11 +21297,8 @@ function buildWrappedMethod(contract, key) {
21291
21297
  operation: 'sendTransaction',
21292
21298
  });
21293
21299
  const pop = await populateTransaction(...args);
21294
- if (runner &&
21295
- 'address' in runner &&
21296
- typeof runner.address == 'string' &&
21297
- pop.from === '0x0000000000000000000000000000000000000000') {
21298
- pop.from = runner.address;
21300
+ if (!pop.from && 'address' in runner && typeof runner.address === 'string') {
21301
+ pop.from = await resolveAddress(runner.address);
21299
21302
  }
21300
21303
  const tx = (await runner.sendTransaction(await pop));
21301
21304
  const provider = getProvider(contract.runner);
@@ -21316,11 +21319,8 @@ function buildWrappedMethod(contract, key) {
21316
21319
  operation: 'call',
21317
21320
  });
21318
21321
  const tx = await populateTransaction(...args);
21319
- if (runner &&
21320
- 'address' in runner &&
21321
- typeof runner.address == 'string' &&
21322
- tx.from === '0x0000000000000000000000000000000000000000') {
21323
- tx.from = runner.address;
21322
+ if (!tx.from && 'address' in runner && typeof runner.address === 'string') {
21323
+ tx.from = await resolveAddress(runner.address);
21324
21324
  }
21325
21325
  let result = '0x';
21326
21326
  try {
@@ -23971,6 +23971,26 @@ class FilterIdPendingSubscriber extends FilterIdSubscriber {
23971
23971
  // @TODO:
23972
23972
  // - Add the batching API
23973
23973
  // https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/ethereum/eth1.0-apis/assembled-spec/openrpc.json&uiSchema%5BappBar%5D%5Bui:splitView%5D=true&uiSchema%5BappBar%5D%5Bui:input%5D=false&uiSchema%5BappBar%5D%5Bui:examplesDropdown%5D=false
23974
+ const Primitive = 'bigint,boolean,function,number,string,symbol'.split(/,/g);
23975
+ function deepCopy(value) {
23976
+ if (value == null || Primitive.indexOf(typeof value) >= 0) {
23977
+ return value;
23978
+ }
23979
+ // Keep any Addressable
23980
+ if (typeof value.getAddress === 'function') {
23981
+ return value;
23982
+ }
23983
+ if (Array.isArray(value)) {
23984
+ return value.map(deepCopy);
23985
+ }
23986
+ if (typeof value === 'object') {
23987
+ return Object.keys(value).reduce((accum, key) => {
23988
+ accum[key] = value[key];
23989
+ return accum;
23990
+ }, {});
23991
+ }
23992
+ throw new Error(`should not happen: ${value} (${typeof value})`);
23993
+ }
23974
23994
  function stall$1(duration) {
23975
23995
  return new Promise((resolve) => {
23976
23996
  setTimeout(resolve, duration);
@@ -23983,6 +24003,183 @@ const defaultOptions = {
23983
24003
  batchMaxCount: 100,
23984
24004
  cacheTimeout: 250,
23985
24005
  };
24006
+ // @TODO: Unchecked Signers
24007
+ class JsonRpcSigner extends AbstractSigner {
24008
+ address;
24009
+ constructor(provider, address) {
24010
+ super(provider);
24011
+ address = getAddress(address);
24012
+ defineProperties(this, { address });
24013
+ }
24014
+ // TODO: `provider` is passed in, but not used, remove?
24015
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
24016
+ connect(provider) {
24017
+ assert(false, 'cannot reconnect JsonRpcSigner', 'UNSUPPORTED_OPERATION', {
24018
+ operation: 'signer.connect',
24019
+ });
24020
+ }
24021
+ async getAddress() {
24022
+ return this.address;
24023
+ }
24024
+ // JSON-RPC will automatially fill in nonce, etc. so we just check from
24025
+ async populateQuaiTransaction(tx) {
24026
+ return (await this.populateCall(tx));
24027
+ }
24028
+ // Returns just the hash of the transaction after sent, which is what
24029
+ // the bare JSON-RPC API does;
24030
+ async sendUncheckedTransaction(_tx) {
24031
+ const tx = deepCopy(_tx);
24032
+ const promises = [];
24033
+ if ('from' in tx) {
24034
+ // Make sure the from matches the sender
24035
+ if (tx.from) {
24036
+ const _from = tx.from;
24037
+ promises.push((async () => {
24038
+ const from = await resolveAddress(_from);
24039
+ assertArgument(from != null && from.toLowerCase() === this.address.toLowerCase(), 'from address mismatch', 'transaction', _tx);
24040
+ tx.from = from;
24041
+ })());
24042
+ }
24043
+ else {
24044
+ tx.from = this.address;
24045
+ }
24046
+ // The JSON-RPC for quai_sendTransaction uses 90000 gas; if the user
24047
+ // wishes to use this, it is easy to specify explicitly, otherwise
24048
+ // we look it up for them.
24049
+ if (tx.gasLimit == null) {
24050
+ promises.push((async () => {
24051
+ tx.gasLimit = await this.provider.estimateGas({ ...tx, from: this.address });
24052
+ })());
24053
+ }
24054
+ // The address may be an ENS name or Addressable
24055
+ if (tx.to != null) {
24056
+ const _to = tx.to;
24057
+ promises.push((async () => {
24058
+ tx.to = await resolveAddress(_to);
24059
+ })());
24060
+ }
24061
+ }
24062
+ else {
24063
+ // Make sure the from matches the sender
24064
+ if (tx.outputs) {
24065
+ for (let i = 0; i < tx.outputs.length; i++) {
24066
+ if (tx.outputs[i].address) {
24067
+ promises.push((async () => {
24068
+ const address = await resolveAddress(hexlify(tx.outputs[i].address));
24069
+ tx.outputs[i].address = getBytes(address);
24070
+ })());
24071
+ }
24072
+ }
24073
+ }
24074
+ }
24075
+ // Wait until all of our properties are filled in
24076
+ if (promises.length) {
24077
+ await Promise.all(promises);
24078
+ }
24079
+ const hexTx = this.provider.getRpcTransaction(tx);
24080
+ return this.provider.send('quai_sendTransaction', [hexTx]);
24081
+ }
24082
+ async sendTransaction(tx) {
24083
+ const zone = await this.zoneFromAddress(addressFromTransactionRequest(tx));
24084
+ // This cannot be mined any earlier than any recent block
24085
+ const blockNumber = await this.provider.getBlockNumber(toShard(zone));
24086
+ // Send the transaction
24087
+ const hash = await this.sendUncheckedTransaction(tx);
24088
+ // Unfortunately, JSON-RPC only provides and opaque transaction hash
24089
+ // for a response, and we need the actual transaction, so we poll
24090
+ // for it; it should show up very quickly
24091
+ return await new Promise((resolve, reject) => {
24092
+ const timeouts = [1000, 100];
24093
+ let invalids = 0;
24094
+ const checkTx = async () => {
24095
+ try {
24096
+ // Try getting the transaction
24097
+ const tx = await this.provider.getTransaction(hash);
24098
+ if (tx != null) {
24099
+ resolve(tx.replaceableTransaction(blockNumber));
24100
+ return;
24101
+ }
24102
+ }
24103
+ catch (error) {
24104
+ // If we were cancelled: stop polling.
24105
+ // If the data is bad: the node returns bad transactions
24106
+ // If the network changed: calling again will also fail
24107
+ // If unsupported: likely destroyed
24108
+ if (isError(error, 'CANCELLED') ||
24109
+ isError(error, 'BAD_DATA') ||
24110
+ isError(error, 'NETWORK_ERROR' )) {
24111
+ if (error.info == null) {
24112
+ error.info = {};
24113
+ }
24114
+ error.info.sendTransactionHash = hash;
24115
+ reject(error);
24116
+ return;
24117
+ }
24118
+ // Stop-gap for misbehaving backends; see #4513
24119
+ if (isError(error, 'INVALID_ARGUMENT')) {
24120
+ invalids++;
24121
+ if (error.info == null) {
24122
+ error.info = {};
24123
+ }
24124
+ error.info.sendTransactionHash = hash;
24125
+ if (invalids > 10) {
24126
+ reject(error);
24127
+ return;
24128
+ }
24129
+ }
24130
+ // Notify anyone that cares; but we will try again, since
24131
+ // it is likely an intermittent service error
24132
+ this.provider.emit('error', makeError('failed to fetch transation after sending (will try again)', 'UNKNOWN_ERROR', {
24133
+ error,
24134
+ }));
24135
+ }
24136
+ // Wait another 4 seconds
24137
+ this.provider._setTimeout(() => {
24138
+ checkTx();
24139
+ }, timeouts.pop() || 4000);
24140
+ };
24141
+ checkTx();
24142
+ });
24143
+ }
24144
+ async signTransaction(_tx) {
24145
+ const tx = deepCopy(_tx);
24146
+ // QuaiTransactionRequest
24147
+ if ('from' in tx) {
24148
+ if (tx.from) {
24149
+ const from = await resolveAddress(tx.from);
24150
+ assertArgument(from != null && from.toLowerCase() === this.address.toLowerCase(), 'from address mismatch', 'transaction', _tx);
24151
+ tx.from = from;
24152
+ }
24153
+ else {
24154
+ tx.from = this.address;
24155
+ }
24156
+ }
24157
+ else {
24158
+ throw new Error('No QI signing implementation in provider-jsonrpc');
24159
+ }
24160
+ const hexTx = this.provider.getRpcTransaction(tx);
24161
+ return await this.provider.send('quai_signTransaction', [hexTx]);
24162
+ }
24163
+ async signMessage(_message) {
24164
+ const message = typeof _message === 'string' ? toUtf8Bytes(_message) : _message;
24165
+ return await this.provider.send('personal_sign', [hexlify(message), this.address.toLowerCase()]);
24166
+ }
24167
+ async signTypedData(domain, types, _value) {
24168
+ const value = deepCopy(_value);
24169
+ return await this.provider.send('quai_signTypedData_v4', [
24170
+ this.address.toLowerCase(),
24171
+ JSON.stringify(TypedDataEncoder.getPayload(domain, types, value)),
24172
+ ]);
24173
+ }
24174
+ async unlock(password) {
24175
+ return this.provider.send('personal_unlockAccount', [this.address.toLowerCase(), password, null]);
24176
+ }
24177
+ // https://github.com/ethereum/wiki/wiki/JSON-RPC#quai_sign
24178
+ async _legacySignMessage(_message) {
24179
+ const message = typeof _message === 'string' ? toUtf8Bytes(_message) : _message;
24180
+ return await this.provider.send('quai_sign', [this.address.toLowerCase(), hexlify(message)]);
24181
+ }
24182
+ }
23986
24183
  /**
23987
24184
  * The JsonRpcApiProvider is an abstract class and **MUST** be sub-classed.
23988
24185
  *
@@ -24600,6 +24797,36 @@ class JsonRpcApiProvider extends AbstractProvider {
24600
24797
  this.#scheduleDrain();
24601
24798
  return promise;
24602
24799
  }
24800
+ async getSigner(address) {
24801
+ if (address == null) {
24802
+ address = 0;
24803
+ }
24804
+ const accountsPromise = this.send('quai_accounts', []);
24805
+ // Account index
24806
+ if (typeof address === 'number') {
24807
+ const accounts = await accountsPromise;
24808
+ if (address >= accounts.length) {
24809
+ throw new Error('no such account');
24810
+ }
24811
+ return new JsonRpcSigner(this, accounts[address]);
24812
+ }
24813
+ const { accounts } = await resolveProperties({
24814
+ network: this.getNetwork(),
24815
+ accounts: accountsPromise,
24816
+ });
24817
+ // Account address
24818
+ address = getAddress(address);
24819
+ for (const account of accounts) {
24820
+ if (getAddress(account) === address) {
24821
+ return new JsonRpcSigner(this, address);
24822
+ }
24823
+ }
24824
+ throw new Error('invalid account');
24825
+ }
24826
+ async listAccounts() {
24827
+ const accounts = await this.send('quai_accounts', []);
24828
+ return accounts.map((a) => new JsonRpcSigner(this, a));
24829
+ }
24603
24830
  destroy() {
24604
24831
  // Stop processing requests
24605
24832
  if (this.#drainTimer) {
@@ -24764,6 +24991,17 @@ class BrowserProvider extends JsonRpcApiProvider {
24764
24991
  }
24765
24992
  };
24766
24993
  }
24994
+ async hasSigner(address) {
24995
+ if (address == null) {
24996
+ address = 0;
24997
+ }
24998
+ const accounts = await this.send('quai_accounts', []);
24999
+ if (typeof address === 'number') {
25000
+ return accounts.length > address;
25001
+ }
25002
+ address = address.toLowerCase();
25003
+ return accounts.filter((a) => a.toLowerCase() === address).length !== 0;
25004
+ }
24767
25005
  async send(method, params) {
24768
25006
  await this._start();
24769
25007
  return await super.send(method, params);
@@ -24797,6 +25035,23 @@ class BrowserProvider extends JsonRpcApiProvider {
24797
25035
  }
24798
25036
  return super.getRpcError(payload, error);
24799
25037
  }
25038
+ async getSigner(address) {
25039
+ if (address == null) {
25040
+ address = 0;
25041
+ }
25042
+ if (!(await this.hasSigner(address))) {
25043
+ try {
25044
+ //const resp =
25045
+ await this.#request('quai_requestAccounts', []);
25046
+ //console.log("RESP", resp);
25047
+ }
25048
+ catch (error) {
25049
+ const payload = error.payload;
25050
+ throw this.getRpcError(payload, { id: payload.id, error });
25051
+ }
25052
+ }
25053
+ return await super.getSigner(address);
25054
+ }
24800
25055
  }
24801
25056
 
24802
25057
  /**
@@ -25319,17 +25574,6 @@ class AbstractSigner {
25319
25574
  // the end for better batching
25320
25575
  return await resolveProperties(pop);
25321
25576
  }
25322
- async populateQiTransaction(tx) {
25323
- const pop = {
25324
- inputsUTXO: tx.inputs,
25325
- outputsUTXO: tx.outputs,
25326
- chainId: tx.chainId,
25327
- type: 2,
25328
- };
25329
- //@TOOD: Don't await all over the place; save them up for
25330
- // the end for better batching
25331
- return await resolveProperties(pop);
25332
- }
25333
25577
  async estimateGas(tx) {
25334
25578
  return checkProvider(this, 'estimateGas').estimateGas(await this.populateCall(tx));
25335
25579
  }
@@ -25338,20 +25582,12 @@ class AbstractSigner {
25338
25582
  }
25339
25583
  async sendTransaction(tx) {
25340
25584
  const provider = checkProvider(this, 'sendTransaction');
25341
- const sender = await this.getAddress();
25342
25585
  const zone = await this.zoneFromAddress(addressFromTransactionRequest(tx));
25343
- let pop;
25344
- let txObj;
25345
- if (isQiAddress(sender)) {
25346
- pop = await this.populateQiTransaction(tx);
25347
- txObj = QiTransaction.from(pop);
25348
- }
25349
- else {
25350
- pop = await this.populateQuaiTransaction(tx);
25351
- txObj = QuaiTransaction.from(pop);
25352
- }
25586
+ const pop = await this.populateQuaiTransaction(tx);
25587
+ const txObj = QuaiTransaction.from(pop);
25588
+ const sender = await this.getAddress();
25353
25589
  const signedTx = await this.signTransaction(txObj);
25354
- return await provider.broadcastTransaction(zone, signedTx, 'from' in tx ? tx.from : undefined);
25590
+ return await provider.broadcastTransaction(zone, signedTx, sender);
25355
25591
  }
25356
25592
  }
25357
25593
  /**
@@ -25470,16 +25706,16 @@ class BaseWallet extends AbstractSigner {
25470
25706
  to: tx.to ? resolveAddress(tx.to) : undefined,
25471
25707
  from: tx.from ? resolveAddress(tx.from) : undefined,
25472
25708
  });
25473
- if (to != null) {
25709
+ if (to !== undefined) {
25474
25710
  validateAddress(to);
25475
25711
  tx.to = to;
25476
25712
  }
25477
- if (from != null) {
25478
- validateAddress(from);
25479
- tx.from = from;
25713
+ if (from !== undefined) {
25714
+ assertArgument(getAddress(from) === this.#address, 'transaction from address mismatch', 'tx.from', from);
25480
25715
  }
25481
- if (tx.from != null) {
25482
- assertArgument(getAddress(tx.from) === this.#address, 'transaction from address mismatch', 'tx.from', tx.from);
25716
+ else {
25717
+ // No `from` specified, use the wallet's address
25718
+ tx.from = this.#address;
25483
25719
  }
25484
25720
  const btx = QuaiTransaction.from(tx);
25485
25721
  const digest = keccak256(btx.unsignedSerialized);
@@ -27048,7 +27284,8 @@ class HDNodeVoidWallet extends VoidSigner {
27048
27284
  // Constant to represent the maximum attempt to derive an address
27049
27285
  const MAX_ADDRESS_DERIVATION_ATTEMPTS = 10000000;
27050
27286
  class AbstractHDWallet {
27051
- static _coinType = 969 ;
27287
+ static _version = 1;
27288
+ static _coinType;
27052
27289
  // Map of account number to HDNodeWallet
27053
27290
  _accounts = new Map();
27054
27291
  // Map of addresses to address info
@@ -27082,7 +27319,7 @@ class AbstractHDWallet {
27082
27319
  return false;
27083
27320
  }
27084
27321
  const isCorrectShard = addressZone === zone;
27085
- const isCorrectLedger = (this.coinType() === 969) ? isQiAddress(address) : !isQiAddress(address);
27322
+ const isCorrectLedger = this.coinType() === 969 ? isQiAddress(address) : !isQiAddress(address);
27086
27323
  return isCorrectShard && isCorrectLedger;
27087
27324
  };
27088
27325
  // derive the address node
@@ -27101,7 +27338,11 @@ class AbstractHDWallet {
27101
27338
  } while (!isValidAddressForZone(addressNode.address));
27102
27339
  return addressNode;
27103
27340
  }
27104
- addAddress(account, addressIndex, zone) {
27341
+ addAddress(account, addressIndex, isChange = false) {
27342
+ return this._addAddress(this._addresses, account, addressIndex, isChange);
27343
+ }
27344
+ // helper method to add an address to the wallet address map
27345
+ _addAddress(addressMap, account, addressIndex, isChange = false) {
27105
27346
  if (!this._accounts.has(account)) {
27106
27347
  this.addAccount(account);
27107
27348
  }
@@ -27111,17 +27352,23 @@ class AbstractHDWallet {
27111
27352
  throw new Error(`Address for index ${addressIndex} already exists`);
27112
27353
  }
27113
27354
  });
27114
- const addressNode = this.deriveAddress(account, addressIndex, zone);
27115
- // create the NeuteredAddressInfo object and update the maps
27355
+ // derive the address node
27356
+ const changeIndex = isChange ? 1 : 0;
27357
+ const addressNode = this._root.deriveChild(account).deriveChild(changeIndex).deriveChild(addressIndex);
27358
+ const zone = getZoneForAddress(addressNode.address);
27359
+ if (!zone) {
27360
+ throw new Error(`Failed to derive a valid address zone for the index ${addressIndex}`);
27361
+ }
27362
+ // create the NeuteredAddressInfo object and update the map
27116
27363
  const neuteredAddressInfo = {
27117
27364
  pubKey: addressNode.publicKey,
27118
27365
  address: addressNode.address,
27119
27366
  account: account,
27120
27367
  index: addressNode.index,
27121
- change: false,
27368
+ change: isChange,
27122
27369
  zone: zone,
27123
27370
  };
27124
- this._addresses.set(neuteredAddressInfo.address, neuteredAddressInfo);
27371
+ addressMap.set(neuteredAddressInfo.address, neuteredAddressInfo);
27125
27372
  return neuteredAddressInfo;
27126
27373
  }
27127
27374
  getNextAddress(accountIndex, zone) {
@@ -27170,7 +27417,7 @@ class AbstractHDWallet {
27170
27417
  }
27171
27418
  static createRandom(password, wordlist) {
27172
27419
  if (password == null) {
27173
- password = "";
27420
+ password = '';
27174
27421
  }
27175
27422
  if (wordlist == null) {
27176
27423
  wordlist = LangEn.wordlist();
@@ -27180,7 +27427,7 @@ class AbstractHDWallet {
27180
27427
  }
27181
27428
  static fromPhrase(phrase, password, wordlist) {
27182
27429
  if (password == null) {
27183
- password = "";
27430
+ password = '';
27184
27431
  }
27185
27432
  if (wordlist == null) {
27186
27433
  wordlist = LangEn.wordlist();
@@ -27196,29 +27443,76 @@ class AbstractHDWallet {
27196
27443
  throw new Error(`Invalid zone: ${zone}`);
27197
27444
  }
27198
27445
  }
27446
+ // Returns the HD node that derives the address.
27447
+ // If the address is not found in the wallet, an error is thrown.
27448
+ _getHDNodeForAddress(addr) {
27449
+ const addressInfo = this._addresses.get(addr);
27450
+ if (!addressInfo) {
27451
+ throw new Error(`Address ${addr} is not known to this wallet`);
27452
+ }
27453
+ // derive a HD node for the from address using the index
27454
+ const accountNode = this._accounts.get(addressInfo.account);
27455
+ if (!accountNode) {
27456
+ throw new Error(`Account ${addressInfo.account} not found`);
27457
+ }
27458
+ const changeIndex = addressInfo.change ? 1 : 0;
27459
+ const changeNode = accountNode.deriveChild(changeIndex);
27460
+ return changeNode.deriveChild(addressInfo.index);
27461
+ }
27462
+ async serialize() {
27463
+ const addresses = Array.from(this._addresses.values());
27464
+ return {
27465
+ version: this.constructor._version,
27466
+ phrase: this._root.mnemonic.phrase,
27467
+ coinType: this.coinType(),
27468
+ addresses: addresses,
27469
+ };
27470
+ }
27471
+ static async deserialize(serialized) {
27472
+ // validate the version and coinType
27473
+ if (serialized.version !== this._version) {
27474
+ throw new Error(`Invalid version ${serialized.version} for wallet (expected ${this._version})`);
27475
+ }
27476
+ if (serialized.coinType !== this._coinType) {
27477
+ throw new Error(`Invalid coinType ${serialized.coinType} for wallet (expected ${this._coinType})`);
27478
+ }
27479
+ // create the wallet instance
27480
+ const mnemonic = Mnemonic.fromPhrase(serialized.phrase);
27481
+ const path = this.parentPath(serialized.coinType);
27482
+ const root = HDNodeWallet.fromMnemonic(mnemonic, path);
27483
+ const wallet = new this(root);
27484
+ // import the addresses
27485
+ wallet.importSerializedAddresses(wallet._addresses, serialized.addresses);
27486
+ return wallet;
27487
+ }
27488
+ // This method is used to import addresses from a serialized wallet.
27489
+ // It validates the addresses and adds them to the wallet.
27490
+ importSerializedAddresses(addressMap, addresses) {
27491
+ for (const addressInfo of addresses) {
27492
+ const newAddressInfo = this._addAddress(addressMap, addressInfo.account, addressInfo.index, addressInfo.change);
27493
+ // validate the address info
27494
+ if (addressInfo.address !== newAddressInfo.address) {
27495
+ throw new Error(`Address mismatch: ${addressInfo.address} != ${newAddressInfo.address}`);
27496
+ }
27497
+ if (addressInfo.pubKey !== newAddressInfo.pubKey) {
27498
+ throw new Error(`Public key mismatch: ${addressInfo.pubKey} != ${newAddressInfo.pubKey}`);
27499
+ }
27500
+ if (addressInfo.zone !== newAddressInfo.zone) {
27501
+ throw new Error(`Zone mismatch: ${addressInfo.zone} != ${newAddressInfo.zone}`);
27502
+ }
27503
+ }
27504
+ }
27199
27505
  }
27200
27506
 
27201
27507
  class QuaiHDWallet extends AbstractHDWallet {
27202
- static _cointype = 994;
27508
+ static _version = 1;
27509
+ static _coinType = 994;
27203
27510
  constructor(root, provider) {
27204
27511
  super(root, provider);
27205
27512
  }
27206
- _getHDNode(from) {
27207
- const fromAddressInfo = this._addresses.get(from);
27208
- if (!fromAddressInfo) {
27209
- throw new Error(`Address ${from} is not known to wallet`);
27210
- }
27211
- // derive a HD node for the from address using the index
27212
- const accountNode = this._accounts.get(fromAddressInfo.account);
27213
- if (!accountNode) {
27214
- throw new Error(`Account ${fromAddressInfo.account} not found`);
27215
- }
27216
- const changeNode = accountNode.deriveChild(0);
27217
- return changeNode.deriveChild(fromAddressInfo.index);
27218
- }
27219
27513
  async signTransaction(tx) {
27220
27514
  const from = await resolveAddress(tx.from);
27221
- const fromNode = this._getHDNode(from);
27515
+ const fromNode = this._getHDNodeForAddress(from);
27222
27516
  const signedTx = await fromNode.signTransaction(tx);
27223
27517
  return signedTx;
27224
27518
  }
@@ -27227,10 +27521,14 @@ class QuaiHDWallet extends AbstractHDWallet {
27227
27521
  throw new Error('Provider is not set');
27228
27522
  }
27229
27523
  const from = await resolveAddress(tx.from);
27230
- const fromNode = this._getHDNode(from);
27524
+ const fromNode = this._getHDNodeForAddress(from);
27231
27525
  const fromNodeConnected = fromNode.connect(this.provider);
27232
27526
  return await fromNodeConnected.sendTransaction(tx);
27233
27527
  }
27528
+ async signMessage(address, message) {
27529
+ const addrNode = this._getHDNodeForAddress(address);
27530
+ return await addrNode.signMessage(message);
27531
+ }
27234
27532
  }
27235
27533
 
27236
27534
  /**
@@ -27746,8 +28044,9 @@ function MuSigFactory(ecc) {
27746
28044
  }
27747
28045
 
27748
28046
  class QiHDWallet extends AbstractHDWallet {
28047
+ static _version = 1;
27749
28048
  static _GAP_LIMIT = 20;
27750
- static _cointype = 969;
28049
+ static _coinType = 969;
27751
28050
  // Map of change addresses to address info
27752
28051
  _changeAddresses = new Map();
27753
28052
  // Array of gap addresses
@@ -27813,7 +28112,7 @@ class QiHDWallet extends AbstractHDWallet {
27813
28112
  }
27814
28113
  async sendTransaction(tx) {
27815
28114
  if (!this.provider) {
27816
- throw new Error("Provider is not set");
28115
+ throw new Error('Provider is not set');
27817
28116
  }
27818
28117
  if (!tx.inputs || tx.inputs.length === 0) {
27819
28118
  throw new Error('Transaction has no inputs');
@@ -27982,6 +28281,61 @@ class QiHDWallet extends AbstractHDWallet {
27982
28281
  const gapChangeAddresses = this._gapChangeAddresses.filter((addressInfo) => addressInfo.zone === zone);
27983
28282
  return gapChangeAddresses;
27984
28283
  }
28284
+ async signMessage(address, message) {
28285
+ const addrNode = this._getHDNodeForAddress(address);
28286
+ const privKey = addrNode.privateKey;
28287
+ const digest = keccak_256(message);
28288
+ const signature = schnorr.sign(digest, getBytes(privKey));
28289
+ return hexlify(signature);
28290
+ }
28291
+ async serialize() {
28292
+ const hdwalletSerialized = await super.serialize();
28293
+ return {
28294
+ outpoints: this._outpoints,
28295
+ changeAddresses: Array.from(this._changeAddresses.values()),
28296
+ gapAddresses: this._gapAddresses,
28297
+ gapChangeAddresses: this._gapChangeAddresses,
28298
+ ...hdwalletSerialized,
28299
+ };
28300
+ }
28301
+ static async deserialize(serialized) {
28302
+ const wallet = await super.deserialize(serialized);
28303
+ // import the change addresses
28304
+ wallet.importSerializedAddresses(wallet._changeAddresses, serialized.changeAddresses);
28305
+ // import the gap addresses, verifying they exist in the wallet
28306
+ for (const gapAddressInfo of serialized.gapAddresses) {
28307
+ const gapAddress = gapAddressInfo.address;
28308
+ if (!wallet._addresses.has(gapAddress)) {
28309
+ throw new Error(`Address ${gapAddress} not found in wallet`);
28310
+ }
28311
+ wallet._gapAddresses.push(gapAddressInfo);
28312
+ }
28313
+ // import the gap change addresses, verifying they exist in the wallet
28314
+ for (const gapChangeAddressInfo of serialized.gapChangeAddresses) {
28315
+ const gapChangeAddress = gapChangeAddressInfo.address;
28316
+ if (!wallet._changeAddresses.has(gapChangeAddress)) {
28317
+ throw new Error(`Address ${gapChangeAddress} not found in wallet`);
28318
+ }
28319
+ wallet._gapChangeAddresses.push(gapChangeAddressInfo);
28320
+ }
28321
+ // validate the outpoints and import them
28322
+ for (const outpointInfo of serialized.outpoints) {
28323
+ // check the zone is valid
28324
+ wallet.validateZone(outpointInfo.zone);
28325
+ // check the outpoint address is known to the wallet
28326
+ if (!wallet._addresses.has(outpointInfo.address)) {
28327
+ throw new Error(`Address ${outpointInfo.address} not found in wallet`);
28328
+ }
28329
+ const outpoint = outpointInfo.outpoint;
28330
+ // TODO: implement a more robust check for Outpoint
28331
+ // check the Outpoint fields are not empty
28332
+ if (outpoint.Txhash == null || outpoint.Index == null || outpoint.Denomination == null) {
28333
+ throw new Error(`Invalid Outpoint: ${JSON.stringify(outpoint)} `);
28334
+ }
28335
+ wallet._outpoints.push(outpointInfo);
28336
+ }
28337
+ return wallet;
28338
+ }
27985
28339
  }
27986
28340
 
27987
28341
  const Base64 = ')!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_';
@@ -28150,6 +28504,7 @@ var quais = /*#__PURE__*/Object.freeze({
28150
28504
  Interface: Interface,
28151
28505
  JsonRpcApiProvider: JsonRpcApiProvider,
28152
28506
  JsonRpcProvider: JsonRpcProvider,
28507
+ JsonRpcSigner: JsonRpcSigner,
28153
28508
  LangEn: LangEn,
28154
28509
  LangEs: LangEs,
28155
28510
  Log: Log,
@@ -28291,5 +28646,5 @@ var quais = /*#__PURE__*/Object.freeze({
28291
28646
  zeroPadValue: zeroPadValue
28292
28647
  });
28293
28648
 
28294
- export { AbiCoder, AbstractProvider, AbstractSigner, AbstractTransaction, BaseContract, BaseWallet, Block, BrowserProvider, ConstructorFragment, Contract, ContractEventPayload, ContractFactory, ContractTransactionReceipt, ContractTransactionResponse, ContractUnknownEventPayload, ErrorDescription, ErrorFragment, EventFragment, EventLog, EventPayload, FallbackFragment, FeeData, FetchCancelSignal, FetchRequest, FetchResponse, FewestCoinSelector, FixedNumber, Fragment, FunctionFragment, HDNodeVoidWallet, Indexed, Interface, JsonRpcApiProvider, JsonRpcProvider, LangEn, LangEs, Log, LogDescription, MaxInt256, MaxUint256, MessagePrefix, MinInt256, Mnemonic, N$1 as N, NamedFragment, Network, ParamType, QiHDWallet, QiTransaction, QuaiHDWallet, QuaiTransaction, Result, Shard, Signature, SigningKey, SocketBlockSubscriber, SocketEventSubscriber, SocketPendingSubscriber, SocketProvider, SocketSubscriber, StructFragment, TransactionDescription, TransactionReceipt, Typed, TypedDataEncoder, UndecodedEventLog, UnmanagedSubscriber, Utf8ErrorFuncs, VoidSigner, Wallet, WebSocketProvider, WeiPerEther, Wordlist, WordlistOwl, WordlistOwlA, ZeroAddress, ZeroHash, Zone, accessListify, assert, assertArgument, assertArgumentCount, assertNormalize, assertPrivate, checkResultErrors, computeAddress, computeHmac, concat, copyRequest, dataLength, dataSlice, decodeBase58, decodeBase64, decodeBytes32String, decodeProtoTransaction, decodeProtoWorkObject, decryptKeystoreJson, decryptKeystoreJsonSync, defineProperties, encodeBase58, encodeBase64, encodeBytes32String, encodeProtoTransaction, encodeProtoWorkObject, encryptKeystoreJson, encryptKeystoreJsonSync, formatEther, formatMixedCaseChecksumAddress, formatQuai, formatUnits, fromTwos, getAddress, getAddressDetails, getBigInt, getBytes, getBytesCopy, getCreate2Address, getCreateAddress, getNumber, getTxType, getUint, getZoneForAddress, hashMessage, hexlify, id, isAddress, isAddressable, isBytesLike, isCallException, isError, isHexString, isKeystoreJson, isQiAddress, keccak256, lock, makeError, mask, musigCrypto, parseEther, parseQuai, parseUnits, pbkdf2, quais, quaisymbol, randomBytes, recoverAddress, resolveAddress, resolveProperties, ripemd160, scrypt, scryptSync, sha256, sha512, solidityPacked, solidityPackedKeccak256, solidityPackedSha256, stripZerosLeft, toBeArray, toBeHex, toBigInt, toNumber, toQuantity, toTwos, toUtf8Bytes, toUtf8CodePoints, toUtf8String, uuidV4, validateAddress, verifyMessage, verifyTypedData, version, wordlists, zeroPadBytes, zeroPadValue };
28649
+ export { AbiCoder, AbstractProvider, AbstractSigner, AbstractTransaction, BaseContract, BaseWallet, Block, BrowserProvider, ConstructorFragment, Contract, ContractEventPayload, ContractFactory, ContractTransactionReceipt, ContractTransactionResponse, ContractUnknownEventPayload, ErrorDescription, ErrorFragment, EventFragment, EventLog, EventPayload, FallbackFragment, FeeData, FetchCancelSignal, FetchRequest, FetchResponse, FewestCoinSelector, FixedNumber, Fragment, FunctionFragment, HDNodeVoidWallet, Indexed, Interface, JsonRpcApiProvider, JsonRpcProvider, JsonRpcSigner, LangEn, LangEs, Log, LogDescription, MaxInt256, MaxUint256, MessagePrefix, MinInt256, Mnemonic, N$1 as N, NamedFragment, Network, ParamType, QiHDWallet, QiTransaction, QuaiHDWallet, QuaiTransaction, Result, Shard, Signature, SigningKey, SocketBlockSubscriber, SocketEventSubscriber, SocketPendingSubscriber, SocketProvider, SocketSubscriber, StructFragment, TransactionDescription, TransactionReceipt, Typed, TypedDataEncoder, UndecodedEventLog, UnmanagedSubscriber, Utf8ErrorFuncs, VoidSigner, Wallet, WebSocketProvider, WeiPerEther, Wordlist, WordlistOwl, WordlistOwlA, ZeroAddress, ZeroHash, Zone, accessListify, assert, assertArgument, assertArgumentCount, assertNormalize, assertPrivate, checkResultErrors, computeAddress, computeHmac, concat, copyRequest, dataLength, dataSlice, decodeBase58, decodeBase64, decodeBytes32String, decodeProtoTransaction, decodeProtoWorkObject, decryptKeystoreJson, decryptKeystoreJsonSync, defineProperties, encodeBase58, encodeBase64, encodeBytes32String, encodeProtoTransaction, encodeProtoWorkObject, encryptKeystoreJson, encryptKeystoreJsonSync, formatEther, formatMixedCaseChecksumAddress, formatQuai, formatUnits, fromTwos, getAddress, getAddressDetails, getBigInt, getBytes, getBytesCopy, getCreate2Address, getCreateAddress, getNumber, getTxType, getUint, getZoneForAddress, hashMessage, hexlify, id, isAddress, isAddressable, isBytesLike, isCallException, isError, isHexString, isKeystoreJson, isQiAddress, keccak256, lock, makeError, mask, musigCrypto, parseEther, parseQuai, parseUnits, pbkdf2, quais, quaisymbol, randomBytes, recoverAddress, resolveAddress, resolveProperties, ripemd160, scrypt, scryptSync, sha256, sha512, solidityPacked, solidityPackedKeccak256, solidityPackedSha256, stripZerosLeft, toBeArray, toBeHex, toBigInt, toNumber, toQuantity, toTwos, toUtf8Bytes, toUtf8CodePoints, toUtf8String, uuidV4, validateAddress, verifyMessage, verifyTypedData, version, wordlists, zeroPadBytes, zeroPadValue };
28295
28650
  //# sourceMappingURL=quais.js.map