@tomo-inc/chains-service 0.0.23 → 0.0.25

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 (51) hide show
  1. package/dist/index.cjs +42 -24
  2. package/dist/index.d.cts +3 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +43 -25
  5. package/package.json +3 -2
  6. package/project.json +1 -1
  7. package/src/__tests__/config.test.ts +46 -0
  8. package/src/__tests__/dogecoin-utils.test.ts +147 -0
  9. package/src/__tests__/evm-utils.test.ts +133 -0
  10. package/src/__tests__/index.test.ts +40 -0
  11. package/src/__tests__/services.test.ts +285 -0
  12. package/src/__tests__/solana-utils.test.ts +131 -0
  13. package/src/__tests__/utils.test.ts +52 -0
  14. package/src/__tests__/wallet.test.ts +350 -0
  15. package/src/api/__tests__/base.test.ts +146 -0
  16. package/src/api/__tests__/index.test.ts +51 -0
  17. package/src/api/__tests__/network.test.ts +153 -0
  18. package/src/api/__tests__/token.test.ts +231 -2
  19. package/src/api/__tests__/transaction.test.ts +121 -6
  20. package/src/api/__tests__/user.test.ts +237 -3
  21. package/src/api/__tests__/wallet.test.ts +174 -4
  22. package/src/api/network.ts +9 -1
  23. package/src/api/utils/__tests__/index.test.ts +91 -0
  24. package/src/api/utils/__tests__/signature.test.ts +124 -0
  25. package/src/api/utils/index.ts +6 -2
  26. package/src/base/__tests__/network.test.ts +119 -0
  27. package/src/base/__tests__/service.test.ts +68 -0
  28. package/src/base/__tests__/token.test.ts +123 -0
  29. package/src/base/__tests__/transaction.test.ts +210 -0
  30. package/src/config.ts +2 -1
  31. package/src/dogecoin/__tests__/base.test.ts +76 -0
  32. package/src/dogecoin/__tests__/rpc.test.ts +465 -0
  33. package/src/dogecoin/__tests__/service-extended.test.ts +420 -0
  34. package/src/dogecoin/__tests__/utils-doge.test.ts +244 -0
  35. package/src/dogecoin/__tests__/utils-extended.test.ts +323 -0
  36. package/src/dogecoin/base.ts +1 -0
  37. package/src/dogecoin/config.ts +2 -2
  38. package/src/dogecoin/rpc.ts +10 -1
  39. package/src/dogecoin/service.ts +9 -5
  40. package/src/evm/__tests__/rpc.test.ts +132 -0
  41. package/src/evm/__tests__/service.test.ts +535 -0
  42. package/src/evm/__tests__/utils.test.ts +170 -0
  43. package/src/evm/service.ts +11 -0
  44. package/src/evm/utils.ts +2 -2
  45. package/src/solana/__tests__/service.test.ts +425 -0
  46. package/src/solana/__tests__/utils.test.ts +937 -0
  47. package/src/solana/config.ts +1 -1
  48. package/src/solana/service.ts +2 -0
  49. package/src/solana/utils.ts +2 -16
  50. package/src/utils/index.ts +1 -1
  51. package/vitest.config.ts +13 -0
package/dist/index.cjs CHANGED
@@ -2925,9 +2925,12 @@ function generateSignature(config) {
2925
2925
  // src/api/utils/index.ts
2926
2926
  var formatJwtToken = (jwtToken) => `Bearer ${jwtToken}`;
2927
2927
  function signRequest(params, clientId, signParams) {
2928
+ if (!params.headers) {
2929
+ params.headers = {};
2930
+ }
2928
2931
  if (typeof signParams === "string") {
2929
2932
  const jwtToken = signParams;
2930
- Object.assign(params.headers ?? {}, {
2933
+ Object.assign(params.headers, {
2931
2934
  "client-id": clientId,
2932
2935
  Authorization: formatJwtToken(jwtToken)
2933
2936
  });
@@ -2942,7 +2945,7 @@ function signRequest(params, clientId, signParams) {
2942
2945
  apiSecret,
2943
2946
  salt
2944
2947
  });
2945
- Object.assign(params.headers ?? {}, {
2948
+ Object.assign(params.headers, {
2946
2949
  "X-APP-Key": apiKey,
2947
2950
  "X-Signature": signature,
2948
2951
  "X-Timestamp": timestamp,
@@ -3854,11 +3857,17 @@ var NetworkAPIs = class _NetworkAPIs extends BasePublicService {
3854
3857
  getCacheId(chainType) {
3855
3858
  return `tomo-${chainType}-currentChainId`;
3856
3859
  }
3860
+ /** Map ChainTypeEnum to network-data platformType where they differ */
3861
+ static platformTypeForChain = {
3862
+ [walletUtils.ChainTypeEnum.DOGECOIN]: "DOGE",
3863
+ [walletUtils.ChainTypeEnum.BITCOIN]: "BTC"
3864
+ };
3857
3865
  getAllNetworks(chainType) {
3858
3866
  if (chainType === "") {
3859
3867
  return this.chains;
3860
3868
  }
3861
- return this.chains.filter((chain) => chain.platformType === chainType.toUpperCase());
3869
+ const platformType = _NetworkAPIs.platformTypeForChain[chainType] ?? chainType.toUpperCase();
3870
+ return this.chains.filter((chain) => chain.platformType === platformType);
3862
3871
  }
3863
3872
  async getCurrentNetwork(chainType) {
3864
3873
  if (!walletUtils.SupportedChainTypes?.[chainType]) {
@@ -3910,7 +3919,8 @@ function getConfig(tomoStage) {
3910
3919
  var CONFIG = {
3911
3920
  prod: getConfig("prod"),
3912
3921
  pre: getConfig("pre"),
3913
- dev: getConfig("dev")
3922
+ dev: getConfig("dev"),
3923
+ "prod-dogeos": getConfig("prod-dogeos")
3914
3924
  };
3915
3925
 
3916
3926
  // src/base/service.ts
@@ -3968,15 +3978,16 @@ function fromBase64(base64) {
3968
3978
  return new Uint8Array(buffer);
3969
3979
  }
3970
3980
  function toBase58(data) {
3981
+ console.warn("toBase58:", data);
3971
3982
  throw new Error("toBase58 requires bs58 package. Install it: pnpm add bs58");
3972
3983
  }
3973
- var BaseConfig = walletUtils.SupportedChainTypes[walletUtils.ChainTypeEnum.DOGE];
3984
+ var BaseConfig = walletUtils.SupportedChainTypes[walletUtils.ChainTypeEnum.DOGECOIN];
3974
3985
  var BLOCK_CONFIRMATIONS = 1;
3975
3986
  var FEE_RATE_KB = 0.5;
3976
3987
  var DECIMALS = 1e8;
3977
3988
  var TRANSACTION_PAGE_SIZE = 10;
3978
3989
  var MYDOGE_BASE_URL = "https://api.mydoge.com";
3979
- var RPC_URL_TOMO = "https://wallet-pro.tomo.inc/rpc/v1/doge_coin";
3990
+ var RPC_URL_TOMO = "https://wallet-test.tomo.inc/rpc/v1/doge_coin";
3980
3991
  var RPC_URL = "https://api.bitcore.io/api/DOGE/mainnet";
3981
3992
  var RPC_TIMEOUT = 20 * 1e3;
3982
3993
  var TX_OVERHEAD = 10;
@@ -4567,11 +4578,7 @@ var DogecoinService = class _DogecoinService extends BaseService {
4567
4578
  gasLimitParam,
4568
4579
  addressList: [txData.from]
4569
4580
  };
4570
- const {
4571
- data: gasInfo,
4572
- success,
4573
- message
4574
- } = await this.transactions.queryGasInfo({
4581
+ const { data: gasInfo, success } = await this.transactions.queryGasInfo({
4575
4582
  chainType: this.chainType,
4576
4583
  params: queryGasParams
4577
4584
  });
@@ -4623,6 +4630,9 @@ var DogecoinService = class _DogecoinService extends BaseService {
4623
4630
  async signPsbt({ psbtHex, options }) {
4624
4631
  const psbtBase64 = toBase64(fromHex(psbtHex));
4625
4632
  const signedPsbt = await this.accountInfo.signTransaction(JSON.stringify({ psbtBase64 }));
4633
+ if (!options) {
4634
+ console.warn("not support options.");
4635
+ }
4626
4636
  if (!signedPsbt) {
4627
4637
  throw new Error("error psbtHex:" + psbtHex);
4628
4638
  }
@@ -4630,6 +4640,7 @@ var DogecoinService = class _DogecoinService extends BaseService {
4630
4640
  return signedRawTx;
4631
4641
  }
4632
4642
  async signPsbts({ psbtHexs, options }) {
4643
+ console.warn("signPsbsts:", psbtHexs, options);
4633
4644
  throw new Error("not implemented");
4634
4645
  }
4635
4646
  async requestTransaction(txData) {
@@ -4659,6 +4670,9 @@ var DogecoinService = class _DogecoinService extends BaseService {
4659
4670
  fee = 0,
4660
4671
  options
4661
4672
  }) {
4673
+ if (options) {
4674
+ console.warn("not support options");
4675
+ }
4662
4676
  if (fee <= 0) {
4663
4677
  throw new Error("fee is required");
4664
4678
  }
@@ -4753,7 +4767,7 @@ var TxTypes = /* @__PURE__ */ ((TxTypes2) => {
4753
4767
 
4754
4768
  // src/evm/utils.ts
4755
4769
  var isEvmChain = (network2) => {
4756
- return network2 && network2?.platformType === "EVM";
4770
+ return network2?.platformType === "EVM" || false;
4757
4771
  };
4758
4772
  var getAllTypeChainIds = ({ chainId, chainType }) => {
4759
4773
  if (viem.isHex(chainId)) {
@@ -4767,7 +4781,7 @@ var getAllTypeChainIds = ({ chainId, chainType }) => {
4767
4781
  }
4768
4782
  const chainIdHex = viem.toHex(Number(chainId));
4769
4783
  return {
4770
- chainId,
4784
+ chainId: String(chainId),
4771
4785
  chainIdHex,
4772
4786
  chainUid: `${chainType}:${chainId}`
4773
4787
  };
@@ -4938,6 +4952,16 @@ var EvmService = class _EvmService extends BaseService {
4938
4952
  }
4939
4953
  };
4940
4954
  }
4955
+ async request(method, params) {
4956
+ try {
4957
+ const rpcClient = await this.createPublicClient({});
4958
+ const res = await rpcClient.request(method, params);
4959
+ return res;
4960
+ } catch (error) {
4961
+ console.error("Failed to request:", error);
4962
+ throw error;
4963
+ }
4964
+ }
4941
4965
  async createPublicClient({ chainId, rpcUrl }) {
4942
4966
  if (rpcUrl) {
4943
4967
  return viem.createPublicClient({
@@ -5081,7 +5105,7 @@ var EvmService = class _EvmService extends BaseService {
5081
5105
  }
5082
5106
  }
5083
5107
  };
5084
- var BaseConfig2 = walletUtils.SupportedChainTypes[walletUtils.ChainTypeEnum.SOL];
5108
+ var BaseConfig2 = walletUtils.SupportedChainTypes[walletUtils.ChainTypeEnum.SOLANA];
5085
5109
  var TOKEN_METADATA_PROGRAM_ID = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s";
5086
5110
  var MSG_PREFIX = "\xFFsolana offchain";
5087
5111
 
@@ -5120,15 +5144,7 @@ async function createLegacyTx({ from = "", to = "", amount = 0 }, connection) {
5120
5144
  transaction.lastValidBlockHeight = lastValidBlockHeight;
5121
5145
  return transaction;
5122
5146
  }
5123
- async function createTokenLegacyTransaction2({
5124
- from = "",
5125
- to = "",
5126
- amount = 0,
5127
- tokenAddress = "",
5128
- priorityFee = 0,
5129
- // microLamports (1 SOL = 1e6 microLamports)
5130
- decimals = 6
5131
- }, connection) {
5147
+ async function createTokenLegacyTransaction2({ from = "", to = "", amount = 0, tokenAddress = "", decimals = 6 }, connection) {
5132
5148
  try {
5133
5149
  const fromPubkey = new web3_js.PublicKey(from);
5134
5150
  const toPubkey = new web3_js.PublicKey(to);
@@ -5281,7 +5297,7 @@ var SolanaService = class _SolanaService extends BaseService {
5281
5297
  web3_js.VersionedTransaction.deserialize(hexBuffer);
5282
5298
  rawTx = hexBuffer;
5283
5299
  } catch (error) {
5284
- const base58Buffer = Buffer.from(toBase58());
5300
+ const base58Buffer = Buffer.from(toBase58(signedTx));
5285
5301
  web3_js.VersionedTransaction.deserialize(base58Buffer);
5286
5302
  rawTx = base58Buffer;
5287
5303
  }
@@ -5333,9 +5349,11 @@ var SolanaService = class _SolanaService extends BaseService {
5333
5349
  return signature;
5334
5350
  }
5335
5351
  async signAllTransactions({ rawTransactions }) {
5352
+ console.warn("signAllTransactions:", rawTransactions);
5336
5353
  throw new Error("no support");
5337
5354
  }
5338
5355
  async signAndSendAllTransactions({ rawTransactions }) {
5356
+ console.warn("signAndSendAllTransactions:", rawTransactions);
5339
5357
  throw new Error("no support");
5340
5358
  }
5341
5359
  async queryRent(params) {
package/dist/index.d.cts CHANGED
@@ -309,6 +309,8 @@ declare class NetworkAPIs extends BasePublicService {
309
309
  private constructor();
310
310
  static getInstance(apiBase: IPublicApiBaseConfig, tomoAppInfo: TomoAppInfo): NetworkAPIs;
311
311
  getCacheId(chainType: ChainTypeEnum | ""): string;
312
+ /** Map ChainTypeEnum to network-data platformType where they differ */
313
+ private static readonly platformTypeForChain;
312
314
  getAllNetworks(chainType: ChainTypeEnum | ""): any[];
313
315
  getCurrentNetwork(chainType: ChainTypeEnum): Promise<string>;
314
316
  setCurrentNetwork(chainType: ChainTypeEnum | "", chainId: string): Promise<void>;
@@ -599,6 +601,7 @@ declare class EvmService extends BaseService {
599
601
  eth_signTypedData_v4([address, typedData]: [`0x${string}`, ITypedData]): Promise<`0x${string}`>;
600
602
  eth_getBalance([address, type]: [`0x${string}`, "latest"]): Promise<string>;
601
603
  _queryGasInfo(txData: TransactionParams$1): Promise<QueryGasResponse>;
604
+ request(method: string, params: any): Promise<any>;
602
605
  private createPublicClient;
603
606
  eth_estimateGas(txs: Transaction$1[]): Promise<`0x${string}`>;
604
607
  eth_getTransactionCount([address, type]: [`0x${string}`, "latest" | "pending"]): Promise<number>;
package/dist/index.d.ts CHANGED
@@ -309,6 +309,8 @@ declare class NetworkAPIs extends BasePublicService {
309
309
  private constructor();
310
310
  static getInstance(apiBase: IPublicApiBaseConfig, tomoAppInfo: TomoAppInfo): NetworkAPIs;
311
311
  getCacheId(chainType: ChainTypeEnum | ""): string;
312
+ /** Map ChainTypeEnum to network-data platformType where they differ */
313
+ private static readonly platformTypeForChain;
312
314
  getAllNetworks(chainType: ChainTypeEnum | ""): any[];
313
315
  getCurrentNetwork(chainType: ChainTypeEnum): Promise<string>;
314
316
  setCurrentNetwork(chainType: ChainTypeEnum | "", chainId: string): Promise<void>;
@@ -599,6 +601,7 @@ declare class EvmService extends BaseService {
599
601
  eth_signTypedData_v4([address, typedData]: [`0x${string}`, ITypedData]): Promise<`0x${string}`>;
600
602
  eth_getBalance([address, type]: [`0x${string}`, "latest"]): Promise<string>;
601
603
  _queryGasInfo(txData: TransactionParams$1): Promise<QueryGasResponse>;
604
+ request(method: string, params: any): Promise<any>;
602
605
  private createPublicClient;
603
606
  eth_estimateGas(txs: Transaction$1[]): Promise<`0x${string}`>;
604
607
  eth_getTransactionCount([address, type]: [`0x${string}`, "latest" | "pending"]): Promise<number>;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { SupportedChainTypes, ChainTypeEnum, TomoApiDomains, cache, getExplorerUrl } from '@tomo-inc/wallet-utils';
1
+ import { ChainTypeEnum, SupportedChainTypes, cache, TomoApiDomains, getExplorerUrl } from '@tomo-inc/wallet-utils';
2
2
  import axios from 'axios';
3
3
  import CryptoJS from 'crypto-js';
4
4
  import Bignumber, { BigNumber } from 'bignumber.js';
@@ -2917,9 +2917,12 @@ function generateSignature(config) {
2917
2917
  // src/api/utils/index.ts
2918
2918
  var formatJwtToken = (jwtToken) => `Bearer ${jwtToken}`;
2919
2919
  function signRequest(params, clientId, signParams) {
2920
+ if (!params.headers) {
2921
+ params.headers = {};
2922
+ }
2920
2923
  if (typeof signParams === "string") {
2921
2924
  const jwtToken = signParams;
2922
- Object.assign(params.headers ?? {}, {
2925
+ Object.assign(params.headers, {
2923
2926
  "client-id": clientId,
2924
2927
  Authorization: formatJwtToken(jwtToken)
2925
2928
  });
@@ -2934,7 +2937,7 @@ function signRequest(params, clientId, signParams) {
2934
2937
  apiSecret,
2935
2938
  salt
2936
2939
  });
2937
- Object.assign(params.headers ?? {}, {
2940
+ Object.assign(params.headers, {
2938
2941
  "X-APP-Key": apiKey,
2939
2942
  "X-Signature": signature,
2940
2943
  "X-Timestamp": timestamp,
@@ -3846,11 +3849,17 @@ var NetworkAPIs = class _NetworkAPIs extends BasePublicService {
3846
3849
  getCacheId(chainType) {
3847
3850
  return `tomo-${chainType}-currentChainId`;
3848
3851
  }
3852
+ /** Map ChainTypeEnum to network-data platformType where they differ */
3853
+ static platformTypeForChain = {
3854
+ [ChainTypeEnum.DOGECOIN]: "DOGE",
3855
+ [ChainTypeEnum.BITCOIN]: "BTC"
3856
+ };
3849
3857
  getAllNetworks(chainType) {
3850
3858
  if (chainType === "") {
3851
3859
  return this.chains;
3852
3860
  }
3853
- return this.chains.filter((chain) => chain.platformType === chainType.toUpperCase());
3861
+ const platformType = _NetworkAPIs.platformTypeForChain[chainType] ?? chainType.toUpperCase();
3862
+ return this.chains.filter((chain) => chain.platformType === platformType);
3854
3863
  }
3855
3864
  async getCurrentNetwork(chainType) {
3856
3865
  if (!SupportedChainTypes?.[chainType]) {
@@ -3902,7 +3911,8 @@ function getConfig(tomoStage) {
3902
3911
  var CONFIG = {
3903
3912
  prod: getConfig("prod"),
3904
3913
  pre: getConfig("pre"),
3905
- dev: getConfig("dev")
3914
+ dev: getConfig("dev"),
3915
+ "prod-dogeos": getConfig("prod-dogeos")
3906
3916
  };
3907
3917
 
3908
3918
  // src/base/service.ts
@@ -3960,15 +3970,16 @@ function fromBase64(base64) {
3960
3970
  return new Uint8Array(buffer);
3961
3971
  }
3962
3972
  function toBase58(data) {
3973
+ console.warn("toBase58:", data);
3963
3974
  throw new Error("toBase58 requires bs58 package. Install it: pnpm add bs58");
3964
3975
  }
3965
- var BaseConfig = SupportedChainTypes[ChainTypeEnum.DOGE];
3976
+ var BaseConfig = SupportedChainTypes[ChainTypeEnum.DOGECOIN];
3966
3977
  var BLOCK_CONFIRMATIONS = 1;
3967
3978
  var FEE_RATE_KB = 0.5;
3968
3979
  var DECIMALS = 1e8;
3969
3980
  var TRANSACTION_PAGE_SIZE = 10;
3970
3981
  var MYDOGE_BASE_URL = "https://api.mydoge.com";
3971
- var RPC_URL_TOMO = "https://wallet-pro.tomo.inc/rpc/v1/doge_coin";
3982
+ var RPC_URL_TOMO = "https://wallet-test.tomo.inc/rpc/v1/doge_coin";
3972
3983
  var RPC_URL = "https://api.bitcore.io/api/DOGE/mainnet";
3973
3984
  var RPC_TIMEOUT = 20 * 1e3;
3974
3985
  var TX_OVERHEAD = 10;
@@ -4559,11 +4570,7 @@ var DogecoinService = class _DogecoinService extends BaseService {
4559
4570
  gasLimitParam,
4560
4571
  addressList: [txData.from]
4561
4572
  };
4562
- const {
4563
- data: gasInfo,
4564
- success,
4565
- message
4566
- } = await this.transactions.queryGasInfo({
4573
+ const { data: gasInfo, success } = await this.transactions.queryGasInfo({
4567
4574
  chainType: this.chainType,
4568
4575
  params: queryGasParams
4569
4576
  });
@@ -4615,6 +4622,9 @@ var DogecoinService = class _DogecoinService extends BaseService {
4615
4622
  async signPsbt({ psbtHex, options }) {
4616
4623
  const psbtBase64 = toBase64(fromHex(psbtHex));
4617
4624
  const signedPsbt = await this.accountInfo.signTransaction(JSON.stringify({ psbtBase64 }));
4625
+ if (!options) {
4626
+ console.warn("not support options.");
4627
+ }
4618
4628
  if (!signedPsbt) {
4619
4629
  throw new Error("error psbtHex:" + psbtHex);
4620
4630
  }
@@ -4622,6 +4632,7 @@ var DogecoinService = class _DogecoinService extends BaseService {
4622
4632
  return signedRawTx;
4623
4633
  }
4624
4634
  async signPsbts({ psbtHexs, options }) {
4635
+ console.warn("signPsbsts:", psbtHexs, options);
4625
4636
  throw new Error("not implemented");
4626
4637
  }
4627
4638
  async requestTransaction(txData) {
@@ -4651,6 +4662,9 @@ var DogecoinService = class _DogecoinService extends BaseService {
4651
4662
  fee = 0,
4652
4663
  options
4653
4664
  }) {
4665
+ if (options) {
4666
+ console.warn("not support options");
4667
+ }
4654
4668
  if (fee <= 0) {
4655
4669
  throw new Error("fee is required");
4656
4670
  }
@@ -4745,7 +4759,7 @@ var TxTypes = /* @__PURE__ */ ((TxTypes2) => {
4745
4759
 
4746
4760
  // src/evm/utils.ts
4747
4761
  var isEvmChain = (network2) => {
4748
- return network2 && network2?.platformType === "EVM";
4762
+ return network2?.platformType === "EVM" || false;
4749
4763
  };
4750
4764
  var getAllTypeChainIds = ({ chainId, chainType }) => {
4751
4765
  if (isHex(chainId)) {
@@ -4759,7 +4773,7 @@ var getAllTypeChainIds = ({ chainId, chainType }) => {
4759
4773
  }
4760
4774
  const chainIdHex = toHex$1(Number(chainId));
4761
4775
  return {
4762
- chainId,
4776
+ chainId: String(chainId),
4763
4777
  chainIdHex,
4764
4778
  chainUid: `${chainType}:${chainId}`
4765
4779
  };
@@ -4930,6 +4944,16 @@ var EvmService = class _EvmService extends BaseService {
4930
4944
  }
4931
4945
  };
4932
4946
  }
4947
+ async request(method, params) {
4948
+ try {
4949
+ const rpcClient = await this.createPublicClient({});
4950
+ const res = await rpcClient.request(method, params);
4951
+ return res;
4952
+ } catch (error) {
4953
+ console.error("Failed to request:", error);
4954
+ throw error;
4955
+ }
4956
+ }
4933
4957
  async createPublicClient({ chainId, rpcUrl }) {
4934
4958
  if (rpcUrl) {
4935
4959
  return createPublicClient({
@@ -5073,7 +5097,7 @@ var EvmService = class _EvmService extends BaseService {
5073
5097
  }
5074
5098
  }
5075
5099
  };
5076
- var BaseConfig2 = SupportedChainTypes[ChainTypeEnum.SOL];
5100
+ var BaseConfig2 = SupportedChainTypes[ChainTypeEnum.SOLANA];
5077
5101
  var TOKEN_METADATA_PROGRAM_ID = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s";
5078
5102
  var MSG_PREFIX = "\xFFsolana offchain";
5079
5103
 
@@ -5112,15 +5136,7 @@ async function createLegacyTx({ from = "", to = "", amount = 0 }, connection) {
5112
5136
  transaction.lastValidBlockHeight = lastValidBlockHeight;
5113
5137
  return transaction;
5114
5138
  }
5115
- async function createTokenLegacyTransaction2({
5116
- from = "",
5117
- to = "",
5118
- amount = 0,
5119
- tokenAddress = "",
5120
- priorityFee = 0,
5121
- // microLamports (1 SOL = 1e6 microLamports)
5122
- decimals = 6
5123
- }, connection) {
5139
+ async function createTokenLegacyTransaction2({ from = "", to = "", amount = 0, tokenAddress = "", decimals = 6 }, connection) {
5124
5140
  try {
5125
5141
  const fromPubkey = new PublicKey(from);
5126
5142
  const toPubkey = new PublicKey(to);
@@ -5273,7 +5289,7 @@ var SolanaService = class _SolanaService extends BaseService {
5273
5289
  VersionedTransaction.deserialize(hexBuffer);
5274
5290
  rawTx = hexBuffer;
5275
5291
  } catch (error) {
5276
- const base58Buffer = Buffer.from(toBase58());
5292
+ const base58Buffer = Buffer.from(toBase58(signedTx));
5277
5293
  VersionedTransaction.deserialize(base58Buffer);
5278
5294
  rawTx = base58Buffer;
5279
5295
  }
@@ -5325,9 +5341,11 @@ var SolanaService = class _SolanaService extends BaseService {
5325
5341
  return signature;
5326
5342
  }
5327
5343
  async signAllTransactions({ rawTransactions }) {
5344
+ console.warn("signAllTransactions:", rawTransactions);
5328
5345
  throw new Error("no support");
5329
5346
  }
5330
5347
  async signAndSendAllTransactions({ rawTransactions }) {
5348
+ console.warn("signAndSendAllTransactions:", rawTransactions);
5331
5349
  throw new Error("no support");
5332
5350
  }
5333
5351
  async queryRent(params) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomo-inc/chains-service",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "author": "tomo.inc",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -23,11 +23,12 @@
23
23
  "bitcoinjs-lib": "^7.0.0",
24
24
  "crypto-js": "4.2.0",
25
25
  "viem": "2.21.54",
26
- "@tomo-inc/wallet-utils": "0.0.18"
26
+ "@tomo-inc/wallet-utils": "0.0.19"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/supertest": "^2.0.12",
30
30
  "@vitest/browser": "^3.2.4",
31
+ "@vitest/coverage-v8": "^3.2.4",
31
32
  "playwright": "^1.44.1",
32
33
  "supertest": "^6.3.0",
33
34
  "tsup": "^8.0.0",
package/project.json CHANGED
@@ -50,7 +50,7 @@
50
50
  "executor": "nx:run-commands",
51
51
  "outputs": ["{projectRoot}/coverage"],
52
52
  "options": {
53
- "command": "vitest run",
53
+ "command": "vitest run --coverage",
54
54
  "cwd": "packages/chains-service"
55
55
  }
56
56
  },
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { CONFIG, getConfig } from "../config";
3
+
4
+ describe("config", () => {
5
+ describe("getConfig", () => {
6
+ it("should throw when tomo stage is invalid", () => {
7
+ expect(() => getConfig("invalid" as any)).toThrow("Invalid tomo stage");
8
+ });
9
+ });
10
+
11
+ describe("CONFIG", () => {
12
+ it("should have config for prod stage", () => {
13
+ expect(CONFIG.prod).toBeDefined();
14
+ expect(CONFIG.prod.rpcBaseUrl).toBeDefined();
15
+ expect(CONFIG.prod.walletBaseUrl).toBeDefined();
16
+ expect(CONFIG.prod.txBaseUrl).toBeDefined();
17
+ expect(CONFIG.prod.tokenBaseUrl).toBeDefined();
18
+ expect(CONFIG.prod.userBaseUrl).toBeDefined();
19
+ });
20
+
21
+ it("should have config for pre stage", () => {
22
+ expect(CONFIG.pre).toBeDefined();
23
+ expect(CONFIG.pre.rpcBaseUrl).toBeDefined();
24
+ expect(CONFIG.pre.walletBaseUrl).toBeDefined();
25
+ expect(CONFIG.pre.txBaseUrl).toBeDefined();
26
+ expect(CONFIG.pre.tokenBaseUrl).toBeDefined();
27
+ expect(CONFIG.pre.userBaseUrl).toBeDefined();
28
+ });
29
+
30
+ it("should have config for dev stage", () => {
31
+ expect(CONFIG.dev).toBeDefined();
32
+ expect(CONFIG.dev.rpcBaseUrl).toBeDefined();
33
+ expect(CONFIG.dev.walletBaseUrl).toBeDefined();
34
+ expect(CONFIG.dev.txBaseUrl).toBeDefined();
35
+ expect(CONFIG.dev.tokenBaseUrl).toBeDefined();
36
+ expect(CONFIG.dev.userBaseUrl).toBeDefined();
37
+ });
38
+
39
+ it("should have correct URL structure", () => {
40
+ expect(CONFIG.dev.walletBaseUrl).toContain("/wallet");
41
+ expect(CONFIG.dev.txBaseUrl).toContain("/quote");
42
+ expect(CONFIG.dev.tokenBaseUrl).toBeDefined();
43
+ expect(CONFIG.dev.userBaseUrl).toContain("/user/api");
44
+ });
45
+ });
46
+ });
@@ -0,0 +1,147 @@
1
+ import * as walletUtils from "@tomo-inc/wallet-utils";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { addUsedUtxos, getUsedUtxos, toBitcoin, toSatoshi, TransactionParser } from "../dogecoin/utils";
4
+
5
+ // Mock cache while preserving other exports
6
+ vi.mock("@tomo-inc/wallet-utils", async (importOriginal) => {
7
+ const actual = await importOriginal<typeof import("@tomo-inc/wallet-utils")>();
8
+ return {
9
+ ...actual,
10
+ cache: {
11
+ get: vi.fn(),
12
+ set: vi.fn(),
13
+ },
14
+ };
15
+ });
16
+
17
+ describe("dogecoin utils", () => {
18
+ beforeEach(() => {
19
+ vi.clearAllMocks();
20
+ });
21
+
22
+ describe("toSatoshi", () => {
23
+ it("should convert DOGE to satoshi", () => {
24
+ expect(toSatoshi(1)).toBe(100000000);
25
+ expect(toSatoshi(0.5)).toBe(50000000);
26
+ expect(toSatoshi("1")).toBe(100000000);
27
+ });
28
+
29
+ it("should throw error for invalid amount", () => {
30
+ expect(() => toSatoshi(-1)).toThrow("Invalid amount");
31
+ expect(() => toSatoshi("invalid")).toThrow();
32
+ });
33
+
34
+ it("should handle zero amount", () => {
35
+ expect(toSatoshi(0)).toBe(0);
36
+ });
37
+ });
38
+
39
+ describe("toBitcoin", () => {
40
+ it("should convert satoshi to DOGE", () => {
41
+ expect(toBitcoin(100000000)).toBe(1);
42
+ expect(toBitcoin(50000000)).toBe(0.5);
43
+ expect(toBitcoin("100000000")).toBe(1);
44
+ });
45
+
46
+ it("should throw error for invalid amount", () => {
47
+ expect(() => toBitcoin(-1)).toThrow("Invalid Koinu amount");
48
+ expect(() => toBitcoin("invalid")).toThrow();
49
+ });
50
+
51
+ it("should handle zero amount", () => {
52
+ expect(toBitcoin(0)).toBe(0);
53
+ });
54
+ });
55
+
56
+ describe("addUsedUtxos", () => {
57
+ it("should add used UTXOs to cache", () => {
58
+ const cache = vi.mocked(walletUtils.cache);
59
+ cache.get.mockReturnValue({});
60
+ cache.set.mockImplementation(() => true);
61
+
62
+ const newUsedUtxos = {
63
+ txid1: 1,
64
+ txid2: 1,
65
+ };
66
+
67
+ addUsedUtxos(newUsedUtxos);
68
+
69
+ expect(cache.set).toHaveBeenCalled();
70
+ });
71
+ });
72
+
73
+ describe("getUsedUtxos", () => {
74
+ it("should get used UTXOs from cache", () => {
75
+ const cache = vi.mocked(walletUtils.cache);
76
+ const mockUsedUtxos = { txid1: 1, txid2: 1 };
77
+ cache.get.mockReturnValue(mockUsedUtxos);
78
+
79
+ const result = getUsedUtxos();
80
+ expect(result).toEqual(mockUsedUtxos);
81
+ });
82
+
83
+ it("should return empty object if cache is empty", () => {
84
+ const cache = vi.mocked(walletUtils.cache);
85
+ cache.get.mockReturnValue(null);
86
+
87
+ const result = getUsedUtxos();
88
+ expect(result).toEqual({});
89
+ });
90
+ });
91
+
92
+ describe("TransactionParser", () => {
93
+ it("should create parser instance", () => {
94
+ const parser = new TransactionParser("rawTxHex");
95
+ expect(parser.rawTx).toBe("rawTxHex");
96
+ });
97
+
98
+ describe("hexToText", () => {
99
+ it("should convert hex to text", () => {
100
+ const parser = new TransactionParser("");
101
+ const result = parser.hexToText("48656c6c6f"); // "Hello" in hex
102
+ expect(result).toBe("Hello");
103
+ });
104
+
105
+ it("should handle empty hex", () => {
106
+ const parser = new TransactionParser("");
107
+ const result = parser.hexToText("");
108
+ expect(result).toBe("");
109
+ });
110
+ });
111
+
112
+ describe("extractOPReturnData", () => {
113
+ it("should extract OP_RETURN data when present", () => {
114
+ const rawTx = "6f72647b2274797065223a2274657374227d"; // Contains "ord" and JSON
115
+ const parser = new TransactionParser(rawTx);
116
+ const result = parser.extractOPReturnData();
117
+ expect(result).toBeDefined();
118
+ });
119
+
120
+ it("should return null when OP_RETURN data not present", () => {
121
+ const parser = new TransactionParser("normalTxData");
122
+ const result = parser.extractOPReturnData();
123
+ expect(result).toBeNull();
124
+ });
125
+ });
126
+
127
+ describe("parseInputs", () => {
128
+ it("should parse transaction inputs", () => {
129
+ const rawTx = "0100000001" + "a".repeat(64) + "00000000" + "6f7264";
130
+ const parser = new TransactionParser(rawTx);
131
+ const inputs = parser.parseInputs();
132
+ expect(Array.isArray(inputs)).toBe(true);
133
+ });
134
+ });
135
+
136
+ describe("parseScript", () => {
137
+ it("should parse transaction script", () => {
138
+ const rawTx = "0100000001" + "a".repeat(64) + "00000000";
139
+ const parser = new TransactionParser(rawTx);
140
+ const result = parser.parseScript();
141
+ expect(result).toHaveProperty("version");
142
+ expect(result).toHaveProperty("inputCount");
143
+ expect(result).toHaveProperty("inputs");
144
+ });
145
+ });
146
+ });
147
+ });