@orb-labs/orby-core 0.0.17 → 0.0.19

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 (36) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/actions/account_cluster.js +2 -1
  3. package/dist/cjs/actions/operation.js +2 -2
  4. package/dist/cjs/constants.js +6 -0
  5. package/dist/cjs/entities/account.d.ts +2 -2
  6. package/dist/cjs/entities/account.js +11 -10
  7. package/dist/cjs/entities/financial/fungible_token.js +5 -4
  8. package/dist/cjs/entities/financial/non_fungible_token.js +4 -4
  9. package/dist/cjs/entities/financial/semi_fungible_token.js +4 -4
  10. package/dist/cjs/enums.d.ts +3 -1
  11. package/dist/cjs/enums.js +2 -0
  12. package/dist/cjs/index.d.ts +1 -0
  13. package/dist/cjs/index.js +1 -0
  14. package/dist/cjs/utils/utils.d.ts +2 -1
  15. package/dist/cjs/utils/utils.js +30 -6
  16. package/dist/cjs/utils/validateAndParseAddress.d.ts +8 -0
  17. package/dist/cjs/utils/validateAndParseAddress.js +52 -0
  18. package/dist/esm/actions/account_cluster.js +2 -1
  19. package/dist/esm/actions/operation.js +2 -2
  20. package/dist/esm/constants.js +6 -0
  21. package/dist/esm/entities/account.d.ts +2 -2
  22. package/dist/esm/entities/account.js +11 -10
  23. package/dist/esm/entities/financial/fungible_token.js +6 -5
  24. package/dist/esm/entities/financial/non_fungible_token.js +5 -5
  25. package/dist/esm/entities/financial/semi_fungible_token.js +5 -5
  26. package/dist/esm/enums.d.ts +3 -1
  27. package/dist/esm/enums.js +2 -0
  28. package/dist/esm/index.d.ts +1 -0
  29. package/dist/esm/index.js +1 -0
  30. package/dist/esm/utils/utils.d.ts +2 -1
  31. package/dist/esm/utils/utils.js +29 -6
  32. package/dist/esm/utils/validateAndParseAddress.d.ts +8 -0
  33. package/dist/esm/utils/validateAndParseAddress.js +48 -0
  34. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  35. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  36. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ ### 0.0.19
6
+
7
+ - fix: use accountType when interacting with the backend
8
+
9
+ ### 0.0.18
10
+
11
+ - chore: update type (using Account.type instead of Account.accountType)
12
+
5
13
  ### 0.0.17
6
14
 
7
15
  - fix: remove 'type': 'module' from package.json
@@ -4,6 +4,7 @@ exports.AccountClusterActions = void 0;
4
4
  const action_helpers_js_1 = require("../utils/action_helpers.js");
5
5
  const library_request_js_1 = require("../entities/library_request.js");
6
6
  const utils_js_1 = require("../utils/utils.js");
7
+ const validateAndParseAddress_js_1 = require("../utils/validateAndParseAddress.js");
7
8
  class AccountClusterActions extends library_request_js_1.LibraryRequest {
8
9
  constructor(library, client, provider) {
9
10
  super(library, client, provider);
@@ -51,7 +52,7 @@ class AccountClusterActions extends library_request_js_1.LibraryRequest {
51
52
  return {
52
53
  chainId: (0, utils_js_1.getChainIdFromOrbyChainId)(info.chainId),
53
54
  virtualNodeRpcUrl: info.virtualNodeRpcUrl,
54
- entrypointAccountAddress: info?.entrypointAccountAddress?.toLowerCase(),
55
+ entrypointAccountAddress: (0, validateAndParseAddress_js_1.validateAndFormatAddress)(info?.entrypointAccountAddress),
55
56
  };
56
57
  });
57
58
  }
@@ -334,7 +334,7 @@ class OperationActions extends library_request_js_1.LibraryRequest {
334
334
  const smartAccountTransactions = operations.reduce((acc, operation) => {
335
335
  const accountKey = account_js_1.Account.key(operation.from, operation.chainId);
336
336
  const account = accountsMap.get(accountKey);
337
- if (account?.accountType == enums_js_1.AccountType.SCA &&
337
+ if (account?.type == enums_js_1.AccountType.SCA &&
338
338
  operation.format == enums_js_1.OperationDataFormat.TRANSACTION) {
339
339
  if (!acc.has(accountKey)) {
340
340
  acc.set(accountKey, []);
@@ -351,7 +351,7 @@ class OperationActions extends library_request_js_1.LibraryRequest {
351
351
  const accountKey = account_js_1.Account.key(operation.from, operation.chainId);
352
352
  const account = accountsMap.get(accountKey);
353
353
  // skip signing the transaction if the account is an SCA
354
- if (account?.accountType == enums_js_1.AccountType.SCA) {
354
+ if (account?.type == enums_js_1.AccountType.SCA) {
355
355
  continue;
356
356
  }
357
357
  signature = await signTransaction(operation);
@@ -20,6 +20,7 @@ exports.BLOCKCHAIN_ID = {
20
20
  [enums_js_1.Blockchain.MOONBEAM]: 1284,
21
21
  [enums_js_1.Blockchain.BASE]: 8453,
22
22
  [enums_js_1.Blockchain.AVALANCHE]: 43114,
23
+ [enums_js_1.Blockchain.SOLANA]: 101,
23
24
  // testnets
24
25
  [enums_js_1.Blockchain.ETHEREUM_SEPOLIA]: 11155111,
25
26
  [enums_js_1.Blockchain.ETHEREUM_HOLESKY]: 17000,
@@ -76,6 +77,10 @@ exports.CHAIN_CONFIGS = {
76
77
  environment: enums_js_1.BlockchainEnvironment.MAINNET,
77
78
  chainId: BigInt(43114),
78
79
  },
80
+ [enums_js_1.Blockchain.SOLANA]: {
81
+ environment: enums_js_1.BlockchainEnvironment.MAINNET,
82
+ chainId: BigInt(101),
83
+ },
79
84
  // testnets
80
85
  [enums_js_1.Blockchain.ETHEREUM_SEPOLIA]: {
81
86
  environment: enums_js_1.BlockchainEnvironment.TESTNET,
@@ -125,6 +130,7 @@ exports.BLOCKCHAIN_ID_TO_BLOCKCHAIN = {
125
130
  [1284]: enums_js_1.Blockchain.MOONBEAM,
126
131
  [8453]: enums_js_1.Blockchain.BASE,
127
132
  [43114]: enums_js_1.Blockchain.AVALANCHE,
133
+ [101]: enums_js_1.Blockchain.SOLANA,
128
134
  // testnets
129
135
  [11155111]: enums_js_1.Blockchain.ETHEREUM_SEPOLIA,
130
136
  [84532]: enums_js_1.Blockchain.BASE_SEPOLIA,
@@ -2,12 +2,12 @@ import { AccountType, VMType } from "../enums.js";
2
2
  export declare class Account {
3
3
  readonly address: string;
4
4
  readonly chainId?: bigint;
5
- readonly accountType: AccountType;
5
+ readonly type: AccountType;
6
6
  readonly vmType: VMType;
7
7
  readonly key: string;
8
8
  hasSufficientBalanceForGas: boolean;
9
9
  static toAccount(account: any): Account;
10
- constructor(address: string, accountType: AccountType, vmType: VMType, chainId?: bigint);
10
+ constructor(address: string, type: AccountType, vmType: VMType, chainId?: bigint);
11
11
  static key(address: string, chainId?: bigint): string;
12
12
  toAccountModel(): any;
13
13
  equals(other: Account): boolean;
@@ -3,26 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Account = void 0;
4
4
  const enums_js_1 = require("../enums.js");
5
5
  const utils_js_1 = require("../utils/utils.js");
6
+ const validateAndParseAddress_js_1 = require("../utils/validateAndParseAddress.js");
6
7
  class Account {
7
8
  static toAccount(account) {
8
9
  const chainId = account?.chainId
9
10
  ? (0, utils_js_1.getChainIdFromOrbyChainId)(account.chainId)
10
11
  : undefined;
11
- const formattedAccountType = account?.accountType;
12
- if (!chainId && formattedAccountType == enums_js_1.AccountType.SCA) {
12
+ if (!chainId && account?.accountType == enums_js_1.AccountType.SCA) {
13
13
  return undefined;
14
14
  }
15
- return new Account(account.address, formattedAccountType, account.vmType, chainId);
15
+ return new Account(account.address, account?.accountType, // backend uses accountType, frontend uses type
16
+ account.vmType, chainId);
16
17
  }
17
- constructor(address, accountType, vmType, chainId) {
18
+ constructor(address, type, vmType, chainId) {
18
19
  // TODO(felix): add this back
19
20
  // invariant(!_.isUndefined(getBlockchainFromBlockchainId(chainId)), "CHAIN_ID");
20
- this.address = address?.toLowerCase(); // validateAndParseAddress(address)?.toLowerCase();
21
+ this.address = (0, validateAndParseAddress_js_1.validateAndFormatAddress)(address);
21
22
  this.chainId = chainId ? BigInt(chainId) : undefined;
22
- this.accountType = accountType;
23
+ this.type = type;
23
24
  this.vmType = vmType;
24
25
  this.key = Account.key(address, chainId);
25
- if (this.accountType == enums_js_1.AccountType.SCA) {
26
+ if (this.type == enums_js_1.AccountType.SCA) {
26
27
  this.hasSufficientBalanceForGas = true;
27
28
  }
28
29
  else {
@@ -31,19 +32,19 @@ class Account {
31
32
  }
32
33
  static key(address, chainId) {
33
34
  return chainId
34
- ? `${chainId?.toString()?.toLowerCase()}-${address}`
35
+ ? `${chainId?.toString()}-${(0, validateAndParseAddress_js_1.validateAndFormatAddress)(address)}`
35
36
  : address;
36
37
  }
37
38
  toAccountModel() {
38
39
  return {
39
40
  address: this.address,
40
- accountType: this.accountType?.toUpperCase(),
41
+ accountType: this.type?.toUpperCase(), // backend uses accountType, frontend uses type
41
42
  vmType: this.vmType?.toUpperCase(),
42
43
  chainId: this.chainId ? "EIP155-" + this.chainId : undefined,
43
44
  };
44
45
  }
45
46
  equals(other) {
46
- return this.key == other?.key && this.accountType == other?.accountType;
47
+ return this.key == other?.key && this.type == other?.type;
47
48
  }
48
49
  }
49
50
  exports.Account = Account;
@@ -31,10 +31,10 @@ class FungibleToken extends currency_js_1.Currency {
31
31
  // TODO(felix): bypassChecksum is a little confusing since when bypassChecksum is true, we still validate the address
32
32
  // bypassChecksum is derived from the isNative parameter, so we should remove it and just check if isNative here
33
33
  if (bypassChecksum) {
34
- this.address = (0, validateAndParseAddress_js_1.checkValidAddress)(address)?.toLowerCase();
34
+ this.address = (0, validateAndParseAddress_js_1.validateAndFormatAddress)(address);
35
35
  }
36
36
  else if (!isNative) {
37
- this.address = (0, validateAndParseAddress_js_1.validateAndParseAddress)(address)?.toLowerCase();
37
+ this.address = (0, validateAndParseAddress_js_1.validateAndFormatAddress)(address);
38
38
  }
39
39
  else {
40
40
  this.address = address;
@@ -50,7 +50,8 @@ class FungibleToken extends currency_js_1.Currency {
50
50
  if (this === other)
51
51
  return true;
52
52
  return (this.chainId == other?.chainId &&
53
- this.address.toLowerCase() == other?.address?.toLowerCase());
53
+ (0, validateAndParseAddress_js_1.validateAndFormatAddress)(this.address) ==
54
+ (0, validateAndParseAddress_js_1.validateAndFormatAddress)(other?.address));
54
55
  }
55
56
  /**
56
57
  * Returns the currency object that this token represents
@@ -62,7 +63,7 @@ class FungibleToken extends currency_js_1.Currency {
62
63
  return enums_js_1.TokenType.FUNGIBLE_TOKEN;
63
64
  }
64
65
  identifier() {
65
- return `${this.chainId}+${this.address.toLowerCase()}`;
66
+ return `${this.chainId}+${(0, validateAndParseAddress_js_1.validateAndFormatAddress)(this.address)}`;
66
67
  }
67
68
  }
68
69
  exports.FungibleToken = FungibleToken;
@@ -23,10 +23,10 @@ class NonFungibleToken extends asset_js_1.Asset {
23
23
  this.isNative = false;
24
24
  this.isToken = true;
25
25
  if (bypassChecksum) {
26
- this.address = (0, validateAndParseAddress_js_1.checkValidAddress)(address)?.toLowerCase();
26
+ this.address = (0, validateAndParseAddress_js_1.validateAndFormatAddress)(address);
27
27
  }
28
28
  else {
29
- this.address = (0, validateAndParseAddress_js_1.validateAndParseAddress)(address)?.toLowerCase();
29
+ this.address = (0, validateAndParseAddress_js_1.validateAndFormatAddress)(address);
30
30
  }
31
31
  this.chainId = chainId;
32
32
  this.url = url;
@@ -47,7 +47,7 @@ class NonFungibleToken extends asset_js_1.Asset {
47
47
  if (this === other)
48
48
  return true;
49
49
  return (this.chainId === other.chainId &&
50
- this.address === other.address.toLowerCase());
50
+ this.address === (0, validateAndParseAddress_js_1.validateAndFormatAddress)(other.address));
51
51
  }
52
52
  /**
53
53
  * Returns the asset representation of this currency
@@ -59,7 +59,7 @@ class NonFungibleToken extends asset_js_1.Asset {
59
59
  return enums_js_1.TokenType.NON_FUNGIBLE_TOKEN;
60
60
  }
61
61
  identifier() {
62
- return `${this.chainId}+${this.address.toLowerCase()}`;
62
+ return `${this.chainId}+${(0, validateAndParseAddress_js_1.validateAndFormatAddress)(this.address)}`;
63
63
  }
64
64
  }
65
65
  exports.NonFungibleToken = NonFungibleToken;
@@ -25,10 +25,10 @@ class SemiFungibleToken extends currency_js_1.Currency {
25
25
  this.isNative = false;
26
26
  this.isToken = true;
27
27
  if (bypassChecksum) {
28
- this.address = (0, validateAndParseAddress_js_1.checkValidAddress)(address)?.toLowerCase();
28
+ this.address = (0, validateAndParseAddress_js_1.validateAndFormatAddress)(address);
29
29
  }
30
30
  else {
31
- this.address = (0, validateAndParseAddress_js_1.validateAndParseAddress)(address)?.toLowerCase();
31
+ this.address = (0, validateAndParseAddress_js_1.validateAndFormatAddress)(address);
32
32
  }
33
33
  this.chainId = chainId;
34
34
  this.url = url;
@@ -49,7 +49,7 @@ class SemiFungibleToken extends currency_js_1.Currency {
49
49
  if (this === other)
50
50
  return true;
51
51
  return (this.chainId === other.chainId &&
52
- this.address === other.address.toLowerCase());
52
+ this.address === (0, validateAndParseAddress_js_1.validateAndFormatAddress)(other.address));
53
53
  }
54
54
  /**
55
55
  * Returns the currency object that this token represents
@@ -61,7 +61,7 @@ class SemiFungibleToken extends currency_js_1.Currency {
61
61
  return enums_js_1.TokenType.SEMI_FUNGIBLE_TOKEN;
62
62
  }
63
63
  identifier() {
64
- return `${this.chainId}+${this.address.toLowerCase()}`;
64
+ return `${this.chainId}+${(0, validateAndParseAddress_js_1.validateAndFormatAddress)(this.address)}`;
65
65
  }
66
66
  }
67
67
  exports.SemiFungibleToken = SemiFungibleToken;
@@ -9,6 +9,7 @@ export declare enum Blockchain {
9
9
  OPTIMISM = "optimism",
10
10
  EVMOS = "evmos",
11
11
  MOONBEAM = "moonbeam",
12
+ SOLANA = "solana",
12
13
  ETHEREUM_SEPOLIA = "ethereum_sepolia",
13
14
  ETHEREUM_HOLESKY = "ethereum_holesky",
14
15
  BASE_SEPOLIA = "base_sepolia",
@@ -33,7 +34,8 @@ export declare enum AccountType {
33
34
  SCA = "SCA"
34
35
  }
35
36
  export declare enum VMType {
36
- EVM = "EVM"
37
+ EVM = "EVM",
38
+ SVM = "SVM"
37
39
  }
38
40
  export declare enum ChainSupportStatus {
39
41
  CHAIN_SUPPORTED = "CHAIN_SUPPORTED",
package/dist/cjs/enums.js CHANGED
@@ -13,6 +13,7 @@ var Blockchain;
13
13
  Blockchain["OPTIMISM"] = "optimism";
14
14
  Blockchain["EVMOS"] = "evmos";
15
15
  Blockchain["MOONBEAM"] = "moonbeam";
16
+ Blockchain["SOLANA"] = "solana";
16
17
  // testnets
17
18
  Blockchain["ETHEREUM_SEPOLIA"] = "ethereum_sepolia";
18
19
  Blockchain["ETHEREUM_HOLESKY"] = "ethereum_holesky";
@@ -43,6 +44,7 @@ var AccountType;
43
44
  var VMType;
44
45
  (function (VMType) {
45
46
  VMType["EVM"] = "EVM";
47
+ VMType["SVM"] = "SVM";
46
48
  })(VMType || (exports.VMType = VMType = {}));
47
49
  var ChainSupportStatus;
48
50
  (function (ChainSupportStatus) {
@@ -27,3 +27,4 @@ export * from "./enums.js";
27
27
  export * from "./types.js";
28
28
  export * from "./constants.js";
29
29
  export * from "./utils/utils.js";
30
+ export * from "./utils/validateAndParseAddress.js";
package/dist/cjs/index.js CHANGED
@@ -47,3 +47,4 @@ __exportStar(require("./enums.js"), exports);
47
47
  __exportStar(require("./types.js"), exports);
48
48
  __exportStar(require("./constants.js"), exports);
49
49
  __exportStar(require("./utils/utils.js"), exports);
50
+ __exportStar(require("./utils/validateAndParseAddress.js"), exports);
@@ -1,5 +1,6 @@
1
- import { Blockchain } from "../enums.js";
1
+ import { Blockchain, VMType } from "../enums.js";
2
2
  export declare const getChainIdFromOrbyChainId: (value: string) => bigint | undefined;
3
+ export declare const getVirtualEnvironment: (id: bigint) => VMType;
3
4
  export declare const getOrbyChainId: (chainId: bigint) => string;
4
5
  export declare const getBlockchainIdFromBlockchain: (blockchain: Blockchain) => number;
5
6
  export declare const hasError: (data: any) => {
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isMainnet = exports.getBlockchainFromName = exports.hasError = exports.getBlockchainIdFromBlockchain = exports.getOrbyChainId = exports.getChainIdFromOrbyChainId = void 0;
3
+ exports.isMainnet = exports.getBlockchainFromName = exports.hasError = exports.getBlockchainIdFromBlockchain = exports.getOrbyChainId = exports.getVirtualEnvironment = exports.getChainIdFromOrbyChainId = void 0;
4
4
  const enums_js_1 = require("../enums.js");
5
5
  const constants_js_1 = require("../constants.js");
6
+ const validateAndParseAddress_js_1 = require("./validateAndParseAddress.js");
6
7
  const getChainIdFromOrbyChainId = (value) => {
7
8
  let chainId = undefined;
8
- const formattedValue = value?.trim()?.toLowerCase();
9
+ const formattedValue = (0, validateAndParseAddress_js_1.validateAndLowerCase)(value);
9
10
  if (formattedValue?.includes("eip155")) {
10
11
  const publicIdElements = formattedValue.split("eip155-");
11
12
  const potentialId = publicIdElements?.length > 1 ? publicIdElements[1] : undefined;
@@ -13,6 +14,13 @@ const getChainIdFromOrbyChainId = (value) => {
13
14
  ? BigInt(potentialId)
14
15
  : undefined;
15
16
  }
17
+ else if (formattedValue?.includes("svm")) {
18
+ const publicIdElements = formattedValue.split("svm-");
19
+ const potentialId = publicIdElements?.length > 1 ? publicIdElements[1] : undefined;
20
+ chainId = !Number.isNaN(Number(potentialId))
21
+ ? BigInt(potentialId)
22
+ : undefined;
23
+ }
16
24
  else {
17
25
  const blockchain = (0, exports.getBlockchainFromName)(formattedValue);
18
26
  const potentialId = blockchain
@@ -23,11 +31,27 @@ const getChainIdFromOrbyChainId = (value) => {
23
31
  return chainId;
24
32
  };
25
33
  exports.getChainIdFromOrbyChainId = getChainIdFromOrbyChainId;
34
+ const getVirtualEnvironment = (id) => {
35
+ const blockchain = id ? constants_js_1.BLOCKCHAIN_ID_TO_BLOCKCHAIN[Number(id)] : undefined;
36
+ switch (blockchain) {
37
+ case undefined:
38
+ return undefined;
39
+ case enums_js_1.Blockchain.SOLANA:
40
+ return enums_js_1.VMType.SVM;
41
+ default:
42
+ return enums_js_1.VMType.EVM;
43
+ }
44
+ };
45
+ exports.getVirtualEnvironment = getVirtualEnvironment;
26
46
  const getOrbyChainId = (chainId) => {
27
- if (!chainId) {
28
- return undefined;
47
+ switch ((0, exports.getVirtualEnvironment)(chainId)) {
48
+ case enums_js_1.VMType.SVM:
49
+ return `SVM-${chainId.toString()}`;
50
+ case enums_js_1.VMType.EVM:
51
+ return `EIP155-${chainId.toString()}`;
52
+ default:
53
+ return undefined;
29
54
  }
30
- return `EIP155-${chainId.toString()}`;
31
55
  };
32
56
  exports.getOrbyChainId = getOrbyChainId;
33
57
  const getBlockchainIdFromBlockchain = (blockchain) => {
@@ -42,7 +66,7 @@ const hasError = (data) => {
42
66
  };
43
67
  exports.hasError = hasError;
44
68
  const getBlockchainFromName = (chainName) => {
45
- const formattedChainName = chainName?.toLowerCase()?.replace("-", "_");
69
+ const formattedChainName = (0, validateAndParseAddress_js_1.validateAndLowerCase)(chainName)?.replace("-", "_");
46
70
  switch (formattedChainName) {
47
71
  case "bnbt": {
48
72
  return enums_js_1.Blockchain.BINANCE_TESTNET;
@@ -8,3 +8,11 @@ export declare function validateAndParseAddress(address: string): string;
8
8
  * @param address the unchecksummed hex address
9
9
  */
10
10
  export declare function checkValidAddress(address: string): string;
11
+ /**
12
+ * Checks if an address is valid by checking 0x prefix, length === 42 and hex encoding.
13
+ * @param address the unchecksummed hex address
14
+ */
15
+ export declare function checkValidEVMAddress(address: string): string;
16
+ export declare function checkValidSVMAddress(address: string): string;
17
+ export declare function validateAndFormatAddress(address?: string): string;
18
+ export declare function validateAndLowerCase(value?: string): string;
@@ -2,6 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateAndParseAddress = validateAndParseAddress;
4
4
  exports.checkValidAddress = checkValidAddress;
5
+ exports.checkValidEVMAddress = checkValidEVMAddress;
6
+ exports.checkValidSVMAddress = checkValidSVMAddress;
7
+ exports.validateAndFormatAddress = validateAndFormatAddress;
8
+ exports.validateAndLowerCase = validateAndLowerCase;
5
9
  const address_1 = require("@ethersproject/address");
6
10
  /**
7
11
  * Validates an address and returns the parsed (checksummed) version of that address
@@ -27,3 +31,51 @@ function checkValidAddress(address) {
27
31
  }
28
32
  throw new Error(`${address} is not a valid address.`);
29
33
  }
34
+ /**
35
+ * Checks if an address is valid by checking 0x prefix, length === 42 and hex encoding.
36
+ * @param address the unchecksummed hex address
37
+ */
38
+ function checkValidEVMAddress(address) {
39
+ if (startsWith0xLen42HexRegex.test(address)) {
40
+ return address.toLowerCase();
41
+ }
42
+ throw new Error(`${address} is not a valid address.`);
43
+ }
44
+ // Solana address validation
45
+ // Base58 character set: [1-9A-HJ-NP-Za-km-z]
46
+ // Standard Solana addresses are 32-44 characters long
47
+ const solanaRegex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
48
+ function checkValidSVMAddress(address) {
49
+ if (solanaRegex.test(address)) {
50
+ return address;
51
+ }
52
+ throw new Error(`${address} is not a valid address.`);
53
+ }
54
+ // for ETH and SOL addresses.
55
+ // ETH addresses are 42 characters long, starting with 0x
56
+ // SOL addresses are 32-44 characters long, containing only alphanumeric characters
57
+ function validateAndFormatAddress(address) {
58
+ if (!address) {
59
+ return undefined;
60
+ }
61
+ // Remove any whitespace
62
+ address = address?.trim();
63
+ if (startsWith0xLen42HexRegex.test(address)) {
64
+ return address.toLowerCase();
65
+ }
66
+ else if (solanaRegex.test(address)) {
67
+ return address;
68
+ }
69
+ return undefined;
70
+ }
71
+ function validateAndLowerCase(value) {
72
+ if (!value) {
73
+ return undefined;
74
+ }
75
+ // Remove any whitespace
76
+ value = value?.trim();
77
+ if (solanaRegex.test(value)) {
78
+ throw new Error(`should not lowwercase solana address: ${value}`);
79
+ }
80
+ return value?.toLowerCase();
81
+ }
@@ -1,6 +1,7 @@
1
1
  import { extractAccountCluster, extractActivities, extractFungibleTokenOverview, extractStandardizedBalances, } from "../utils/action_helpers.js";
2
2
  import { LibraryRequest } from "../entities/library_request.js";
3
3
  import { getChainIdFromOrbyChainId, getOrbyChainId } from "../utils/utils.js";
4
+ import { validateAndFormatAddress } from "../utils/validateAndParseAddress.js";
4
5
  export class AccountClusterActions extends LibraryRequest {
5
6
  constructor(library, client, provider) {
6
7
  super(library, client, provider);
@@ -48,7 +49,7 @@ export class AccountClusterActions extends LibraryRequest {
48
49
  return {
49
50
  chainId: getChainIdFromOrbyChainId(info.chainId),
50
51
  virtualNodeRpcUrl: info.virtualNodeRpcUrl,
51
- entrypointAccountAddress: info?.entrypointAccountAddress?.toLowerCase(),
52
+ entrypointAccountAddress: validateAndFormatAddress(info?.entrypointAccountAddress),
52
53
  };
53
54
  });
54
55
  }
@@ -331,7 +331,7 @@ export class OperationActions extends LibraryRequest {
331
331
  const smartAccountTransactions = operations.reduce((acc, operation) => {
332
332
  const accountKey = Account.key(operation.from, operation.chainId);
333
333
  const account = accountsMap.get(accountKey);
334
- if (account?.accountType == AccountType.SCA &&
334
+ if (account?.type == AccountType.SCA &&
335
335
  operation.format == OperationDataFormat.TRANSACTION) {
336
336
  if (!acc.has(accountKey)) {
337
337
  acc.set(accountKey, []);
@@ -348,7 +348,7 @@ export class OperationActions extends LibraryRequest {
348
348
  const accountKey = Account.key(operation.from, operation.chainId);
349
349
  const account = accountsMap.get(accountKey);
350
350
  // skip signing the transaction if the account is an SCA
351
- if (account?.accountType == AccountType.SCA) {
351
+ if (account?.type == AccountType.SCA) {
352
352
  continue;
353
353
  }
354
354
  signature = await signTransaction(operation);
@@ -14,6 +14,7 @@ export const BLOCKCHAIN_ID = {
14
14
  [Blockchain.MOONBEAM]: 1284,
15
15
  [Blockchain.BASE]: 8453,
16
16
  [Blockchain.AVALANCHE]: 43114,
17
+ [Blockchain.SOLANA]: 101,
17
18
  // testnets
18
19
  [Blockchain.ETHEREUM_SEPOLIA]: 11155111,
19
20
  [Blockchain.ETHEREUM_HOLESKY]: 17000,
@@ -70,6 +71,10 @@ export const CHAIN_CONFIGS = {
70
71
  environment: BlockchainEnvironment.MAINNET,
71
72
  chainId: BigInt(43114),
72
73
  },
74
+ [Blockchain.SOLANA]: {
75
+ environment: BlockchainEnvironment.MAINNET,
76
+ chainId: BigInt(101),
77
+ },
73
78
  // testnets
74
79
  [Blockchain.ETHEREUM_SEPOLIA]: {
75
80
  environment: BlockchainEnvironment.TESTNET,
@@ -119,6 +124,7 @@ export const BLOCKCHAIN_ID_TO_BLOCKCHAIN = {
119
124
  [1284]: Blockchain.MOONBEAM,
120
125
  [8453]: Blockchain.BASE,
121
126
  [43114]: Blockchain.AVALANCHE,
127
+ [101]: Blockchain.SOLANA,
122
128
  // testnets
123
129
  [11155111]: Blockchain.ETHEREUM_SEPOLIA,
124
130
  [84532]: Blockchain.BASE_SEPOLIA,
@@ -2,12 +2,12 @@ import { AccountType, VMType } from "../enums.js";
2
2
  export declare class Account {
3
3
  readonly address: string;
4
4
  readonly chainId?: bigint;
5
- readonly accountType: AccountType;
5
+ readonly type: AccountType;
6
6
  readonly vmType: VMType;
7
7
  readonly key: string;
8
8
  hasSufficientBalanceForGas: boolean;
9
9
  static toAccount(account: any): Account;
10
- constructor(address: string, accountType: AccountType, vmType: VMType, chainId?: bigint);
10
+ constructor(address: string, type: AccountType, vmType: VMType, chainId?: bigint);
11
11
  static key(address: string, chainId?: bigint): string;
12
12
  toAccountModel(): any;
13
13
  equals(other: Account): boolean;
@@ -1,25 +1,26 @@
1
1
  import { AccountType } from "../enums.js";
2
2
  import { getChainIdFromOrbyChainId } from "../utils/utils.js";
3
+ import { validateAndFormatAddress } from "../utils/validateAndParseAddress.js";
3
4
  export class Account {
4
5
  static toAccount(account) {
5
6
  const chainId = account?.chainId
6
7
  ? getChainIdFromOrbyChainId(account.chainId)
7
8
  : undefined;
8
- const formattedAccountType = account?.accountType;
9
- if (!chainId && formattedAccountType == AccountType.SCA) {
9
+ if (!chainId && account?.accountType == AccountType.SCA) {
10
10
  return undefined;
11
11
  }
12
- return new Account(account.address, formattedAccountType, account.vmType, chainId);
12
+ return new Account(account.address, account?.accountType, // backend uses accountType, frontend uses type
13
+ account.vmType, chainId);
13
14
  }
14
- constructor(address, accountType, vmType, chainId) {
15
+ constructor(address, type, vmType, chainId) {
15
16
  // TODO(felix): add this back
16
17
  // invariant(!_.isUndefined(getBlockchainFromBlockchainId(chainId)), "CHAIN_ID");
17
- this.address = address?.toLowerCase(); // validateAndParseAddress(address)?.toLowerCase();
18
+ this.address = validateAndFormatAddress(address);
18
19
  this.chainId = chainId ? BigInt(chainId) : undefined;
19
- this.accountType = accountType;
20
+ this.type = type;
20
21
  this.vmType = vmType;
21
22
  this.key = Account.key(address, chainId);
22
- if (this.accountType == AccountType.SCA) {
23
+ if (this.type == AccountType.SCA) {
23
24
  this.hasSufficientBalanceForGas = true;
24
25
  }
25
26
  else {
@@ -28,18 +29,18 @@ export class Account {
28
29
  }
29
30
  static key(address, chainId) {
30
31
  return chainId
31
- ? `${chainId?.toString()?.toLowerCase()}-${address}`
32
+ ? `${chainId?.toString()}-${validateAndFormatAddress(address)}`
32
33
  : address;
33
34
  }
34
35
  toAccountModel() {
35
36
  return {
36
37
  address: this.address,
37
- accountType: this.accountType?.toUpperCase(),
38
+ accountType: this.type?.toUpperCase(), // backend uses accountType, frontend uses type
38
39
  vmType: this.vmType?.toUpperCase(),
39
40
  chainId: this.chainId ? "EIP155-" + this.chainId : undefined,
40
41
  };
41
42
  }
42
43
  equals(other) {
43
- return this.key == other?.key && this.accountType == other?.accountType;
44
+ return this.key == other?.key && this.type == other?.type;
44
45
  }
45
46
  }
@@ -1,5 +1,5 @@
1
1
  import { Currency } from "./currency.js";
2
- import { checkValidAddress, validateAndParseAddress, } from "../../utils/validateAndParseAddress.js";
2
+ import { validateAndFormatAddress, } from "../../utils/validateAndParseAddress.js";
3
3
  import { TokenType } from "../../enums.js";
4
4
  /**
5
5
  * Represents an ERC20 token with a unique address and some metadata.
@@ -28,10 +28,10 @@ export class FungibleToken extends Currency {
28
28
  // TODO(felix): bypassChecksum is a little confusing since when bypassChecksum is true, we still validate the address
29
29
  // bypassChecksum is derived from the isNative parameter, so we should remove it and just check if isNative here
30
30
  if (bypassChecksum) {
31
- this.address = checkValidAddress(address)?.toLowerCase();
31
+ this.address = validateAndFormatAddress(address);
32
32
  }
33
33
  else if (!isNative) {
34
- this.address = validateAndParseAddress(address)?.toLowerCase();
34
+ this.address = validateAndFormatAddress(address);
35
35
  }
36
36
  else {
37
37
  this.address = address;
@@ -47,7 +47,8 @@ export class FungibleToken extends Currency {
47
47
  if (this === other)
48
48
  return true;
49
49
  return (this.chainId == other?.chainId &&
50
- this.address.toLowerCase() == other?.address?.toLowerCase());
50
+ validateAndFormatAddress(this.address) ==
51
+ validateAndFormatAddress(other?.address));
51
52
  }
52
53
  /**
53
54
  * Returns the currency object that this token represents
@@ -59,6 +60,6 @@ export class FungibleToken extends Currency {
59
60
  return TokenType.FUNGIBLE_TOKEN;
60
61
  }
61
62
  identifier() {
62
- return `${this.chainId}+${this.address.toLowerCase()}`;
63
+ return `${this.chainId}+${validateAndFormatAddress(this.address)}`;
63
64
  }
64
65
  }