diff --git a/sdk/js-connect/core/base/package.json b/sdk/js-connect/core/base/package.json index 7f01c201a8..3660f13267 100644 --- a/sdk/js-connect/core/base/package.json +++ b/sdk/js-connect/core/base/package.json @@ -17,8 +17,7 @@ "module": "./lib/esm/index.js", "types": "./lib/esm/index.d.ts", "files": [ - "lib/**/*", - "src/**/*" + "lib/**/*" ], "dependencies": { "@scure/base": "^1.1.3" diff --git a/sdk/js-connect/core/base/src/constants/circle.ts b/sdk/js-connect/core/base/src/constants/circle.ts index 89e0bc3e52..75f91dc9fd 100644 --- a/sdk/js-connect/core/base/src/constants/circle.ts +++ b/sdk/js-connect/core/base/src/constants/circle.ts @@ -9,28 +9,37 @@ const circleAPIs = [ // https://developers.circle.com/stablecoin/docs/cctp-technical-reference#domain-list const circleDomains = [ - ["Ethereum", 0], + ["Ethereum", 0], ["Avalanche", 1], - ["Optimism", 2], - ["Arbitrum", 3], - ["Base", 6], + ["Optimism", 2], + ["Arbitrum", 3], + ["Solana", 5], + ["Base", 6], ] as const satisfies MapLevel; -const usdcContracts = [[ - "Mainnet", [ - ["Ethereum", "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"], - ["Avalanche", "0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e"], - ["Arbitrum", "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"], - ["Optimism", "0x179522635726710dd7d2035a81d856de4aa7836c"], - ["Base", "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"], - ]], [ - "Testnet", [ - ["Avalanche", "0x5425890298aed601595a70AB815c96711a31Bc65"], - ["Arbitrum", "0xfd064A18f3BF249cf1f87FC203E90D8f650f2d63"], - ["Ethereum", "0x07865c6e87b9f70255377e024ace6630c1eaa37f"], - ["Optimism", "0xe05606174bac4A6364B31bd0eCA4bf4dD368f8C6"], - ["Base", "0xf175520c52418dfe19c8098071a252da48cd1c19"], - ]], +const usdcContracts = [ + [ + "Mainnet", + [ + ["Ethereum", "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"], + ["Avalanche", "0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e"], + ["Arbitrum", "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"], + ["Optimism", "0x179522635726710dd7d2035a81d856de4aa7836c"], + ["Solana", "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"], + ["Base", "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"], + ], + ], + [ + "Testnet", + [ + ["Avalanche", "0x5425890298aed601595a70AB815c96711a31Bc65"], + ["Arbitrum", "0xfd064A18f3BF249cf1f87FC203E90D8f650f2d63"], + ["Ethereum", "0x07865c6e87b9f70255377e024ace6630c1eaa37f"], + ["Optimism", "0xe05606174bac4A6364B31bd0eCA4bf4dD368f8C6"], + ["Solana", "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"], + ["Base", "0xf175520c52418dfe19c8098071a252da48cd1c19"], + ], + ], ] as const satisfies MapLevel>; export const [circleChains, circleChainIds] = zip(circleDomains); @@ -46,8 +55,7 @@ export const circleAPI = constMap(circleAPIs); export const usdcContract = constMap(usdcContracts); -export const isCircleChain = (chain: string): chain is CircleChain => - circleChainId.has(chain); +export const isCircleChain = (chain: string): chain is CircleChain => circleChainId.has(chain); export const isCircleChainId = (chainId: number): chainId is CircleChainId => circleChainIdToChain.has(chainId); @@ -85,7 +93,7 @@ export const toCircleChainId = (chain: number | bigint | string): CircleChainId throw Error(`Cannot convert to ChainId: ${chain}`); }; -export const toCircleChain = (chain: number | string | bigint): Chain => { +export const toCircleChain = (chain: number | string | bigint): CircleChain => { switch (typeof chain) { case "string": if (isCircleChain(chain)) return chain; diff --git a/sdk/js-connect/core/base/src/constants/contracts/circle.ts b/sdk/js-connect/core/base/src/constants/contracts/circle.ts index b603443ef0..013d03eb6d 100644 --- a/sdk/js-connect/core/base/src/constants/contracts/circle.ts +++ b/sdk/js-connect/core/base/src/constants/contracts/circle.ts @@ -73,5 +73,12 @@ export const circleContracts = [[ wormholeRelayer: "", wormhole: "0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c", }], + [ + "Solana", { + tokenMessenger: 'CCTPiPYPc6AsJuwueEnWgSgucamXDZwBd53dQ11YiKX3', + messageTransmitter: 'CCTPmbSD7gX1bxKPAmg77w8oFzNFpaQiQUWD43TKaecd', + wormholeRelayer:"", + wormhole:"" + }] ]], ] as const satisfies MapLevel>; diff --git a/sdk/js-connect/core/base/src/constants/contracts/tokenBridgeRelayer.ts b/sdk/js-connect/core/base/src/constants/contracts/tokenBridgeRelayer.ts index 2dbf489213..39e6f3d1d8 100644 --- a/sdk/js-connect/core/base/src/constants/contracts/tokenBridgeRelayer.ts +++ b/sdk/js-connect/core/base/src/constants/contracts/tokenBridgeRelayer.ts @@ -2,29 +2,35 @@ import { MapLevel } from "../../utils"; import { Network } from "../networks"; import { Chain } from "../chains"; -export const tokenBridgeRelayerContracts = [[ - "Mainnet", [ - ["Ethereum", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], - ["Bsc", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], - ["Polygon", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], - ["Avalanche", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], - ["Fantom", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], - ["Celo", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], - ["Sui", "0x57f4e0ba41a7045e29d435bc66cc4175f381eb700e6ec16d4fdfe92e5a4dff9f"], - ["Solana", "3vxKRPwUTiEkeUVyoZ9MXFe1V71sRLbLqu1gRYaWmehQ"], - ["Base", "0xaE8dc4a7438801Ec4edC0B035EcCCcF3807F4CC1"], - ["Moonbeam", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], - ]], [ - "Testnet", [ - ["Ethereum", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], - ["Bsc", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], - ["Polygon", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], - ["Avalanche", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], - ["Fantom", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], - ["Celo", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], - ["Sui", "0xb30040e5120f8cb853b691cb6d45981ae884b1d68521a9dc7c3ae881c0031923"], - ["Solana", "3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg"], - ["Base", "0xae8dc4a7438801ec4edc0b035eccccf3807f4cc1"], - ["Moonbeam", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], - ]], +export const tokenBridgeRelayerContracts = [ + [ + "Mainnet", + [ + ["Ethereum", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], + ["Bsc", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], + ["Polygon", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], + ["Avalanche", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], + ["Fantom", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], + ["Celo", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], + ["Sui", "0x57f4e0ba41a7045e29d435bc66cc4175f381eb700e6ec16d4fdfe92e5a4dff9f"], + ["Solana", "3vxKRPwUTiEkeUVyoZ9MXFe1V71sRLbLqu1gRYaWmehQ"], + ["Base", "0xaE8dc4a7438801Ec4edC0B035EcCCcF3807F4CC1"], + ["Moonbeam", "0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"], + ], + ], + [ + "Testnet", + [ + ["Ethereum", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], + ["Bsc", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], + ["Polygon", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], + ["Avalanche", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], + ["Fantom", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], + ["Celo", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], + ["Sui", "0xb30040e5120f8cb853b691cb6d45981ae884b1d68521a9dc7c3ae881c0031923"], + ["Base", "0xae8dc4a7438801ec4edc0b035eccccf3807f4cc1"], + ["Moonbeam", "0x9563a59c15842a6f322b10f69d1dd88b41f2e97b"], + ["Solana", "3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg"], + ], + ], ] as const satisfies MapLevel>; diff --git a/sdk/js-connect/core/base/src/constants/guardians.ts b/sdk/js-connect/core/base/src/constants/guardians.ts new file mode 100644 index 0000000000..001a3b4827 --- /dev/null +++ b/sdk/js-connect/core/base/src/constants/guardians.ts @@ -0,0 +1,37 @@ +import { RoArray, constMap } from "../utils"; +import { Network } from "./networks"; + +const guardianNamesAndKeys = [ + [ + "Mainnet", + [ + ["JumpCrypto", "0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5"], + ["Staked", "0xfF6CB952589BDE862c25Ef4392132fb9D4A42157"], + ["Figment", "0x114De8460193bdf3A2fCf81f86a09765F4762fD1"], + ["ChainodeTech", "0x107A0086b32d7A0977926A205131d8731D39cbEB"], + ["Inotel", "0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2"], + ["HashQuark", "0x11b39756C042441BE6D8650b69b54EbE715E2343"], + ["Chainlayer", "0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd"], + ["xLabs", "0x15e7cAF07C4e3DC8e7C469f92C8Cd88FB8005a20"], + ["Forbole", "0x74a3bf913953D695260D88BC1aA25A4eeE363ef0"], + ["StakingFund", "0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e"], + ["MoonletWallet", "0xAF45Ced136b9D9e24903464AE889F5C8a723FC14"], + ["P2PValidator", "0xf93124b7c738843CBB89E864c862c38cddCccF95"], + ["01Node", "0xD2CC37A4dc036a8D232b48f62cDD4731412f4890"], + ["MCF", "0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811"], + ["Everstake", "0x71AA1BE1D36CaFE3867910F99C09e347899C19C3"], + ["ChorusOne", "0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf"], + ["Syncnode", "0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8"], + ["Triton", "0x5E1487F35515d02A92753504a8D75471b9f49EdB"], + ["StakingFacilities", "0x6FbEBc898F403E4773E95feB15E80C9A99c8348d"], + ], + ], + ["Testnet", [["Testnet guardian", "0x13947Bd48b18E53fdAeEe77F3473391aC727C638"]]], + ["Devnet", [["", ""]]], +] as const satisfies RoArray]>; + +export const guardianKeys = constMap(guardianNamesAndKeys); +export const guardianNames = constMap(guardianNamesAndKeys, [[0, 2], 1]); + +export const devnetGuardianPrivateKey = + "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"; diff --git a/sdk/js-connect/core/base/src/constants/index.ts b/sdk/js-connect/core/base/src/constants/index.ts index 0fbcd8a919..64c119894e 100644 --- a/sdk/js-connect/core/base/src/constants/index.ts +++ b/sdk/js-connect/core/base/src/constants/index.ts @@ -1,10 +1,28 @@ export { Network } from "./networks"; export { ProtocolName } from "./protocols"; -export { Chain, ChainId, isChain, toChainId, toChain, chains, chainToChainId, chainIdToChain } from "./chains"; -export { Platform, PlatformToChains, ChainToPlatform, PlatformAddressFormat, isPlatform, platformToChains, chainToPlatform } from "./platforms"; +export { + Chain, + ChainId, + isChain, + toChainId, + toChain, + chains, + chainToChainId, + chainIdToChain, +} from "./chains"; +export { + Platform, + PlatformToChains, + ChainToPlatform, + PlatformAddressFormat, + isPlatform, + platformToChains, + chainToPlatform, + platformToAddressFormat, +} from "./platforms"; -export * as platform from './platforms' -export * as chain from './chains' +export * as platform from "./platforms"; +export * as chain from "./chains"; export * as network from "./networks"; export * as finality from "./finality"; export * as decimals from "./decimals"; @@ -13,3 +31,4 @@ export * as rpc from "./rpc"; export * as nativeChainIds from "./nativeChainIds"; export * as circle from "./circle"; export * as contracts from "./contracts"; +export * as guardians from "./guardians"; diff --git a/sdk/js-connect/core/base/src/constants/nativeChainIds.ts b/sdk/js-connect/core/base/src/constants/nativeChainIds.ts index fc7b00ca4c..2ea6887cf4 100644 --- a/sdk/js-connect/core/base/src/constants/nativeChainIds.ts +++ b/sdk/js-connect/core/base/src/constants/nativeChainIds.ts @@ -1,148 +1,250 @@ -import { MapLevel, constMap, ToMapping } from "../utils"; +import { MapLevel, constMap, ToMapping, Widen } from "../utils"; import { Chain } from "./chains"; import { Network } from "./networks"; import { Platform, PlatformToChains, chainToPlatform } from "./platforms"; -const chainNetworkNativeChainIdEntries = [[ - "Aptos", [ - ["Mainnet", 1n], - ["Testnet", 2n], - ["Devnet", 0n], - ]], [ - "Algorand", [ - ["Mainnet", "mainnet-v1.0"], - ["Testnet", "testnet-v1.0"], - ["Devnet", "sandnet-v1.0"], - ]], [ - "Near", [ - ["Mainnet", "mainnet"], - ["Testnet", "testnet"], - ]], [ - "Cosmoshub", [ - ["Mainnet", "cosmoshub-4"], - ["Testnet", "theta-testnet-001"], - ]], [ - "Evmos", [ - ["Mainnet", "evmos_9001-2"], - ["Testnet", "evmos_9000-4"], - ["Devnet", "evmos_devnet_fake"], - ]], [ - "Injective", [ - ["Mainnet", "injective-1"], - ["Testnet", "injective-888"], - ["Devnet", "injective_devnet_fake"], - ]], [ - "Osmosis", [ - ["Mainnet", "osmosis-1"], - ["Testnet", "osmo-test-5"], - ]], [ - "Sei", [ - ["Mainnet", "pacific-1"], - ["Testnet", "atlantic-2"], - ]], [ - "Terra", [ - ["Mainnet", "columbus-5"], - ["Testnet", "bombay-12"], - ]], [ - "Terra2", [ - ["Mainnet", "phoenix-1"], - ["Testnet", "pisco-1"], - ]], [ - "Wormchain", [ - ["Mainnet", "wormchain"], - ["Testnet", "wormchain-testnet-0"], - ]], [ - "Xpla", [ - ["Mainnet", "dimension_37-1"], - ["Testnet", "cube_47-5"], - ]], [ - "Kujira", [ - ["Mainnet", "kaiyo-1"], - ["Testnet", "harpoon-4"], - ]], [ - "Solana", [ - ["Mainnet", "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d"], - ["Testnet", "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG"], - ]], [ - "Sui", [ - ["Mainnet", "35834a8a"], - ["Testnet", "4c78adac"], - ]], [ - "Acala", [ - ["Mainnet", 787n], - ["Testnet", 597n], - ]], [ - "Arbitrum", [ - ["Mainnet", 42161n], //arbitrum goerli - ["Testnet", 421613n], - ]], [ - "Aurora", [ - ["Mainnet", 1313161554n], - ["Testnet", 1313161555n], - ]], [ - "Avalanche", [ - ["Mainnet", 43114n], - ["Testnet", 43113n], //fuji - ]], [ - "Base", [ - ["Mainnet", 8453n], - ["Testnet", 84531n], - ]], [ - "Bsc", [ - ["Mainnet", 56n], - ["Testnet", 97n], - ]], [ - "Celo", [ - ["Mainnet", 42220n], - ["Testnet", 44787n], //alfajores - ]], [ - "Ethereum", [ - ["Mainnet", 1n], - ["Testnet", 5n], //goerli - ]], [ - "Fantom", [ - ["Mainnet", 250n], - ["Testnet", 4002n], - ]], [ - "Gnosis", [ - ["Mainnet", 100n], - ["Testnet", 10200n], - ]], [ - "Karura", [ - ["Mainnet", 686n], - ["Testnet", 596n], - ]], [ - "Klaytn", [ - ["Mainnet", 8217n], - ["Testnet", 1001n], //baobab - ]], [ - "Moonbeam", [ - ["Mainnet", 1284n], - ["Testnet", 1287n], //moonbase alpha - ]], [ - "Neon", [ - ["Mainnet", 245022934n], - ["Testnet", 245022940n], - ]], [ - "Oasis", [ - ["Mainnet", 42262n], - ["Testnet", 42261n], - ]], [ - "Optimism", [ - ["Mainnet", 10n], - ["Testnet", 420n], - ]], [ - "Polygon", [ - ["Mainnet", 137n], - ["Testnet", 80001n], //mumbai - ]], [ - "Rootstock", [ - ["Mainnet", 30n], - ["Testnet", 31n], - ]], [ - "Sepolia", [ - ["Testnet", 11155111n], //actually just another ethereum testnet... - ]], +const chainNetworkNativeChainIdEntries = [ + [ + "Aptos", + [ + ["Mainnet", 1n], + ["Testnet", 2n], + ["Devnet", 0n], + ], + ], + [ + "Algorand", + [ + ["Mainnet", "mainnet-v1.0"], + ["Testnet", "testnet-v1.0"], + ["Devnet", "sandnet-v1.0"], + ], + ], + [ + "Near", + [ + ["Mainnet", "mainnet"], + ["Testnet", "testnet"], + ], + ], + [ + "Cosmoshub", + [ + ["Mainnet", "cosmoshub-4"], + ["Testnet", "theta-testnet-001"], + ], + ], + [ + "Evmos", + [ + ["Mainnet", "evmos_9001-2"], + ["Testnet", "evmos_9000-4"], + ["Devnet", "evmos_devnet_fake"], + ], + ], + [ + "Injective", + [ + ["Mainnet", "injective-1"], + ["Testnet", "injective-888"], + ["Devnet", "injective_devnet_fake"], + ], + ], + [ + "Osmosis", + [ + ["Mainnet", "osmosis-1"], + ["Testnet", "osmo-test-5"], + ], + ], + [ + "Sei", + [ + ["Mainnet", "pacific-1"], + ["Testnet", "atlantic-2"], + ], + ], + [ + "Terra", + [ + ["Mainnet", "columbus-5"], + ["Testnet", "bombay-12"], + ], + ], + [ + "Terra2", + [ + ["Mainnet", "phoenix-1"], + ["Testnet", "pisco-1"], + ], + ], + [ + "Wormchain", + [ + ["Mainnet", "wormchain"], + ["Testnet", "wormchain-testnet-0"], + ], + ], + [ + "Xpla", + [ + ["Mainnet", "dimension_37-1"], + ["Testnet", "cube_47-5"], + ], + ], + [ + "Kujira", + [ + ["Mainnet", "kaiyo-1"], + ["Testnet", "harpoon-4"], + ], + ], + [ + "Solana", + [ + ["Mainnet", "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d"], + ["Testnet", "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG"], + ], + ], + [ + "Sui", + [ + ["Mainnet", "35834a8a"], + ["Testnet", "4c78adac"], + ], + ], + [ + "Acala", + [ + ["Mainnet", 787n], + ["Testnet", 597n], + ], + ], + [ + "Arbitrum", + [ + ["Mainnet", 42161n], //arbitrum goerli + ["Testnet", 421613n], + ], + ], + [ + "Aurora", + [ + ["Mainnet", 1313161554n], + ["Testnet", 1313161555n], + ], + ], + [ + "Avalanche", + [ + ["Mainnet", 43114n], + ["Testnet", 43113n], //fuji + ], + ], + [ + "Base", + [ + ["Mainnet", 8453n], + ["Testnet", 84531n], + ], + ], + [ + "Bsc", + [ + ["Mainnet", 56n], + ["Testnet", 97n], + ], + ], + [ + "Celo", + [ + ["Mainnet", 42220n], + ["Testnet", 44787n], //alfajores + ], + ], + [ + "Ethereum", + [ + ["Mainnet", 1n], + ["Testnet", 5n], //goerli + ], + ], + [ + "Fantom", + [ + ["Mainnet", 250n], + ["Testnet", 4002n], + ], + ], + [ + "Gnosis", + [ + ["Mainnet", 100n], + ["Testnet", 10200n], + ], + ], + [ + "Karura", + [ + ["Mainnet", 686n], + ["Testnet", 596n], + ], + ], + [ + "Klaytn", + [ + ["Mainnet", 8217n], + ["Testnet", 1001n], //baobab + ], + ], + [ + "Moonbeam", + [ + ["Mainnet", 1284n], + ["Testnet", 1287n], //moonbase alpha + ], + ], + [ + "Neon", + [ + ["Mainnet", 245022934n], + ["Testnet", 245022940n], + ], + ], + [ + "Oasis", + [ + ["Mainnet", 42262n], + ["Testnet", 42261n], + ], + ], + [ + "Optimism", + [ + ["Mainnet", 10n], + ["Testnet", 420n], + ], + ], + [ + "Polygon", + [ + ["Mainnet", 137n], + ["Testnet", 80001n], //mumbai + ], + ], + [ + "Rootstock", + [ + ["Mainnet", 30n], + ["Testnet", 31n], + ], + ], + [ + "Sepolia", + [ + ["Testnet", 11155111n], //actually just another ethereum testnet... + ], + ], ] as const satisfies MapLevel>; export const networkChainToNativeChainId = constMap(chainNetworkNativeChainIdEntries, [[1, 0], 2]); @@ -154,31 +256,31 @@ export const networkChainToNativeChainId = constMap(chainNetworkNativeChainIdEnt const nativeChainIdToNetworkChain = constMap(chainNetworkNativeChainIdEntries, [2, [1, 0]]); type NetworkChainToNativeChainId = ToMapping; -export type PlatformToNativeChainIds

= - PlatformToChains

extends infer C +export type PlatformToNativeChainIds

= PlatformToChains

extends infer C ? C extends keyof NetworkChainToNativeChainId - ? NetworkChainToNativeChainId[C][keyof NetworkChainToNativeChainId[C]] - : never + ? NetworkChainToNativeChainId[C][keyof NetworkChainToNativeChainId[C]] + : never : never; export type PlatformNativeChainIdToNetworkChainPair< P extends Platform, - CI extends PlatformToNativeChainIds

+ CI extends PlatformToNativeChainIds

, > = PlatformToChains

extends infer C ? ReturnType>[number] extends infer NCP - ? NCP extends readonly [Network, C] - ? NCP - : never - : never + ? NCP extends readonly [Network, C] + ? NCP + : never + : never : never; export function platformNativeChainIdToNetworkChain< - const P extends Platform, - const CI extends PlatformToNativeChainIds

->(platform: P, chainId: CI): PlatformNativeChainIdToNetworkChainPair { + P extends Platform, + CI extends PlatformToNativeChainIds

, +>(platform: P, chainId: Widen): PlatformNativeChainIdToNetworkChainPair { //typescript really struggles to comprehend the types here so we have to help it out - const candidates = nativeChainIdToNetworkChain(chainId) as - readonly (readonly [Network, Chain])[]; + const candidates = nativeChainIdToNetworkChain( + chainId as PlatformToNativeChainIds

, + ) as readonly (readonly [Network, Chain])[]; const mustBeSingleton = candidates.filter(([_, chain]) => chainToPlatform(chain) === platform); if (mustBeSingleton.length !== 1) throw new Error(`Platform ${platform} has multiple chains with native chain id ${chainId}`); diff --git a/sdk/js-connect/core/base/src/constants/rpc.ts b/sdk/js-connect/core/base/src/constants/rpc.ts index ac23779ecf..55bc40b864 100644 --- a/sdk/js-connect/core/base/src/constants/rpc.ts +++ b/sdk/js-connect/core/base/src/constants/rpc.ts @@ -20,9 +20,10 @@ const rpcConfig = [[ ["Cosmoshub", "https://cosmos-rpc.polkachu.com"], ["Evmos", "https://evmos-rpc.polkachu.com"], ["Injective", "https://sentry.tm.injective.network"], - ["Wormchain", "https://wormchain.jumpisolated.com/"], + ["Wormchain", "https://wormchain-rpc.quickapi.com"], ["Xpla", "https://dimension-rpc.xpla.dev"], ["Sei", "https://sei-rpc.polkachu.com/"], + ["Algorand", "https://mainnet-api.algonode.cloud"], ]], [ "Testnet", [ ["Ethereum", "https://rpc.ankr.com/eth_goerli"], @@ -42,8 +43,10 @@ const rpcConfig = [[ ["Osmosis", "https://rpc.testnet.osmosis.zone"], ["Cosmoshub", "https://rpc.sentry-02.theta-testnet.polypore.xyz"], ["Evmos", "https://evmos-testnet-rpc.polkachu.com"], - ["Wormchain", "https://wormchain-testnet.jumpisolated.com"], - ["Xpla", "https://cube-rpc.xpla.dev "], + ["Wormchain", "https://gateway.testnet.xlabs.xyz/"], + ["Xpla", "https://cube-rpc.xpla.dev"], + ["Sepolia", "https://ethereum-sepolia.publicnode.com"], + ["Algorand", "https://testnet-api.algonode.cloud"], ]], [ "Devnet", [ ["Ethereum", "http://eth-devnet:8545"], diff --git a/sdk/js-connect/core/base/src/utils/amount.ts b/sdk/js-connect/core/base/src/utils/amount.ts index 61183a176b..0b780bdb81 100644 --- a/sdk/js-connect/core/base/src/utils/amount.ts +++ b/sdk/js-connect/core/base/src/utils/amount.ts @@ -5,10 +5,7 @@ * @param decimals the number of decimals to normalize to * @returns The amount converted to base units as a BigNumber */ -export function normalizeAmount( - amount: number | string, - decimals: bigint, -): bigint { +export function normalizeAmount(amount: number | string, decimals: bigint): bigint { // If we're passed a number, convert it to a string first // so we can do everything as bigints if (typeof amount === "number") amount = amount.toPrecision(); @@ -16,15 +13,16 @@ export function normalizeAmount( // punting if (amount.includes("e")) throw new Error(`Exponential detected: ${amount}`); - // If its a whole number, just add a decimal place to normalize - if (!amount.includes(".")) amount += ".0"; + // some slightly sketchy string manip - // some slightly sketchy - const [whole, partial] = amount.split("."); - if (partial.length > decimals) - throw new Error( - `Overspecified decimal amount: ${partial.length} > ${decimals}`, - ); + const chunks = amount.split("."); + if (chunks.length > 2) throw "Too many decimals"; + + const [whole, partial] = + chunks.length === 0 ? ["0", ""] : chunks.length === 1 ? [chunks[0], ""] : chunks; + + if (partial && partial.length > decimals) + throw new Error(`Overspecified decimal amount: ${partial.length} > ${decimals}`); // combine whole and partial without decimals const amt = BigInt(whole + partial); @@ -36,3 +34,19 @@ export function normalizeAmount( // finally, produce the number in base units return amt * 10n ** decimals; } + +/** + * Converts a bigint amount to a friendly decimal number as a string + * + * @param amount The number of units as a bigint to convert into the display amount + * @param decimals the number of decimals in the displayAmount + * @returns The amount converted to a nice display string + */ +export function displayAmount(amount: bigint, decimals: bigint, displayDecimals: bigint): string { + // first scale to remove any partial amounts but allowing for full + // precision required by displayDecimals + const amt = amount / 10n ** (decimals - displayDecimals); + const numDec = Number(displayDecimals); + // Final scaling then use the builtin `Number.tofixed` for formatting display amount + return (Number(amt) / 10 ** numDec).toFixed(numDec); +} diff --git a/sdk/js-connect/core/base/src/utils/array.ts b/sdk/js-connect/core/base/src/utils/array.ts index edf2a4aef0..333f6197de 100644 --- a/sdk/js-connect/core/base/src/utils/array.ts +++ b/sdk/js-connect/core/base/src/utils/array.ts @@ -71,8 +71,8 @@ export type Zip = : never export const zip = (arr: Args) => - range(arr[0].length).map(col => - range(arr.length).map(row => arr[row][col]) + range(arr[0]!.length).map(col => + range(arr.length).map(row => arr[row]![col]) ) as unknown as ([Zip] extends [never] ? RoArray2D : Zip); //extracts elements with the given indexes in the specified order, explicitly forbid unions diff --git a/sdk/js-connect/core/base/src/utils/encoding.ts b/sdk/js-connect/core/base/src/utils/encoding.ts index 7190863cd3..4ed7d2b181 100644 --- a/sdk/js-connect/core/base/src/utils/encoding.ts +++ b/sdk/js-connect/core/base/src/utils/encoding.ts @@ -1,6 +1,6 @@ -import { base16, base64, base58 } from '@scure/base'; +import { base16, base64, base58 } from "@scure/base"; -export { bech32 } from '@scure/base'; +export { bech32 } from "@scure/base"; export const stripPrefix = (prefix: string, str: string): string => str.startsWith(prefix) ? str.slice(prefix.length) : str; @@ -11,9 +11,9 @@ export const hex = { decode: (input: string) => base16.decode(stripPrefix("0x", input).toUpperCase()), encode: (input: string | Uint8Array, prefix: boolean = false) => { input = typeof input === "string" ? bytes.encode(input) : input; - return (prefix ? "0x" : "") + base16.encode(input).toLowerCase() - } -} + return (prefix ? "0x" : "") + base16.encode(input).toLowerCase(); + }, +}; // regex string to check if the input could possibly be base64 encoded. // WARNING: There are clear text strings that are NOT base64 encoded that will pass this check. @@ -22,31 +22,44 @@ export const b64 = { valid: (input: string) => isB64Regex.test(input), decode: base64.decode, encode: (input: string | Uint8Array) => - base64.encode(typeof input === "string" ? bytes.encode(input) : input) -} + base64.encode(typeof input === "string" ? bytes.encode(input) : input), +}; export const b58 = { decode: base58.decode, encode: (input: string | Uint8Array) => base58.encode(typeof input === "string" ? bytes.encode(input) : input), -} +}; export const bignum = { - decode: (input: string) => BigInt(input), - encode: (input: bigint, prefix: boolean = false) => (prefix ? "0x" : "") + input.toString(16) -} + decode: (input: string | Uint8Array) => { + if (typeof input !== "string") input = hex.encode(input, true); + if (input === "" || input === "0x") return 0n; + return BigInt(input); + }, + encode: (input: bigint, prefix: boolean = false) => bignum.toString(input, prefix), + toString: (input: bigint, prefix: boolean = false) => { + let str = input.toString(16); + str = str.length % 2 === 1 ? (str = "0" + str) : str; + if (prefix) return "0x" + str; + return str; + }, + toBytes: (input: bigint | number, length?: number) => { + const b = hex.decode(bignum.toString(typeof input === "number" ? BigInt(input) : input)); + if (!length) return b; + return bytes.zpad(b, length); + }, +}; export const bytes = { - encode: (value: string | bigint): Uint8Array => - typeof value === "bigint" - ? bytes.encode(bignum.encode(value)) - : (new TextEncoder()).encode(value), - decode: (value: Uint8Array): string => - (new TextDecoder()).decode(value), + encode: (value: string): Uint8Array => new TextEncoder().encode(value), + decode: (value: Uint8Array): string => new TextDecoder().decode(value), equals: (lhs: Uint8Array, rhs: Uint8Array): boolean => lhs.length === rhs.length && lhs.every((v, i) => v === rhs[i]), - zpad: (arr: Uint8Array, length: number): Uint8Array => - bytes.concat(new Uint8Array(length - arr.length), arr), + zpad: (arr: Uint8Array, length: number, padStart: boolean = true): Uint8Array => + padStart + ? bytes.concat(new Uint8Array(length - arr.length), arr) + : bytes.concat(arr, new Uint8Array(length - arr.length)), concat: (...args: Uint8Array[]): Uint8Array => { const length = args.reduce((acc, curr) => acc + curr.length, 0); const result = new Uint8Array(length); @@ -56,11 +69,5 @@ export const bytes = { offset += arg.length; }); return result; - } -} - - - - - - + }, +}; diff --git a/sdk/js-connect/core/base/src/utils/layout/deserialize.ts b/sdk/js-connect/core/base/src/utils/layout/deserialize.ts index 2858cbca53..b2a2679b12 100644 --- a/sdk/js-connect/core/base/src/utils/layout/deserialize.ts +++ b/sdk/js-connect/core/base/src/utils/layout/deserialize.ts @@ -75,10 +75,10 @@ function deserializeNum( ): readonly [NumSizeToPrimitive, number] { let val = 0n; for (let i = 0; i < bytes; ++i) - val |= BigInt(encoded[offset + i]) << BigInt(8 * (endianness === "big" ? bytes - i - 1 : i)); + val |= BigInt(encoded[offset + i]!) << BigInt(8 * (endianness === "big" ? bytes - i - 1 : i)); //check sign bit if value is indeed signed and adjust accordingly - if (signed && (encoded[offset + (endianness === "big" ? 0 : bytes - 1)] & 0x80)) + if (signed && (encoded[offset + (endianness === "big" ? 0 : bytes - 1)]! & 0x80)) val -= 1n << BigInt(8 * bytes); return [ @@ -193,7 +193,7 @@ function deserializeLayoutItem( if (layouts.length === 0) throw new Error(`switch item has no layouts`); - const hasPlainIds = typeof layouts[0][0] === "number"; + const hasPlainIds = typeof layouts[0]![0] === "number"; const pair = (layouts as any[]).find(([idOrConversionId]) => hasPlainIds ? idOrConversionId === id : (idOrConversionId)[0] === id); diff --git a/sdk/js-connect/core/base/src/utils/layout/discriminate.ts b/sdk/js-connect/core/base/src/utils/layout/discriminate.ts index cf0e46e918..748dd90a3e 100644 --- a/sdk/js-connect/core/base/src/utils/layout/discriminate.ts +++ b/sdk/js-connect/core/base/src/utils/layout/discriminate.ts @@ -124,9 +124,9 @@ function layoutItemMeta( if (offset !== null) { const serializedId = new Uint8Array(idSize); serializeNum(serializedId, 0, idVal, idSize, idEndianness); - caseFixedBytes[caseIndex].push([0, serializedId]); + caseFixedBytes[caseIndex]!.push([0, serializedId]); } - const ret = createLayoutMeta(layout, offset ? idSize : null, caseFixedBytes[caseIndex]); + const ret = createLayoutMeta(layout, offset ? idSize : null, caseFixedBytes[caseIndex]!); return [ret[0] + idSize, ret[1] + idSize] as Bounds; }); @@ -147,17 +147,17 @@ function layoutItemMeta( while (caseIndex < caseFixedBytes.length) { let curItIndex = itIndexes[caseIndex]; const curFixedBytes = caseFixedBytes[caseIndex]; - const [curOffset, curSerialized] = curFixedBytes[curItIndex]; + const [curOffset, curSerialized] = curFixedBytes![curItIndex!]!; if (curOffset + curSerialized.length <= bytePos) { //no fixed byte at this position in this case - ++curItIndex; + ++curItIndex!; - if (curItIndex === curFixedBytes.length) + if (curItIndex === curFixedBytes!.length) return; //we have exhausted all fixed bytes in at least one case - itIndexes[caseIndex] = curItIndex; + itIndexes[caseIndex] = curItIndex!; //jump to the next possible bytePos given the fixed bytes of the current case index - bytePos = curFixedBytes[curItIndex][0]; + bytePos = curFixedBytes![curItIndex!]![0]; break; } @@ -214,8 +214,8 @@ function buildAscendingBounds(sortedBounds: readonly (readonly [Bounds, LayoutIn // currently under consideration, sorted in ascending order of their respective upper bounds let sortedCandidates = [] as (readonly [Size, LayoutIndex])[]; const closeCandidatesBefore = (before: number) => { - while (sortedCandidates.length > 0 && sortedCandidates[0][0] < before) { - const end = sortedCandidates[0][0] + 1; + while (sortedCandidates.length > 0 && sortedCandidates[0]![0] < before) { + const end = sortedCandidates[0]![0] + 1; //remove all candidates that end at the same position const removeIndex = sortedCandidates.findIndex(([upper]) => end <= upper); if (removeIndex === -1) @@ -275,7 +275,7 @@ function generateLayoutDiscriminator( const allLayouts = (1n << BigInt(layouts.length)) - 1n; const fixedKnown = layouts.map(() => [] as FixedBytes); - const sizeBounds = layouts.map((l, i) => createLayoutMeta(l, 0, fixedKnown[i])); + const sizeBounds = layouts.map((l, i) => createLayoutMeta(l, 0, fixedKnown[i]!)); const sortedBounds = sizeBounds.map((b, i) => [b, i] as const).sort(([[l1]], [[l2]]) => l1 - l2); const mustHaveByteAt = (() => { @@ -322,9 +322,9 @@ function generateLayoutDiscriminator( }).map(() => []); for (let i = 0; i < fixedKnown.length; ++i) - for (const [offset, serialized] of fixedKnown[i]) + for (const [offset, serialized] of fixedKnown[i]!) for (let j = 0; j < serialized.length; ++j) - fixedKnownBytes[offset + j].push([serialized[j], i]); + fixedKnownBytes[offset + j]!.push([serialized[j]!, i]); let bestBytes = []; for (const [bytePos, fixedKnownByte] of fixedKnownBytes.entries()) { @@ -365,7 +365,7 @@ function generateLayoutDiscriminator( bitsetToArray( encoded.length <= bytePos ? outOfBoundsLayouts - : distinctValues.get(encoded[bytePos]) ?? emptySet + : distinctValues.get(encoded[bytePos]!) ?? emptySet ) ]; @@ -402,7 +402,7 @@ function generateLayoutDiscriminator( let sizePower = 0; const narrowedBounds = new Map(); for (const candidate of bitsetToArray(candidates)) { - const lower = sizeBounds[candidate][0]; + const lower = sizeBounds[candidate]![0]; const overlap = ascendingBounds.get(lower)! & candidates; narrowedBounds.set(lower, overlap) sizePower = Math.max(sizePower, count(overlap)); @@ -456,9 +456,9 @@ function generateLayoutDiscriminator( narrowedBestBytes.sort(([lhsPower], [rhsPower]) => rhsPower - lhsPower); //prefer byte discriminators over size discriminators - if (narrowedBestBytes.length > 0 && narrowedBestBytes[0][0] >= sizePower) { + if (narrowedBestBytes.length > 0 && narrowedBestBytes[0]![0] >= sizePower) { const [, bytePos, narrowedOutOfBoundsLayouts, narrowedDistinctValues, anyValueLayouts] = - narrowedBestBytes[0]; + narrowedBestBytes[0]!; addStrategy(candidates, [bytePos, narrowedOutOfBoundsLayouts, narrowedDistinctValues]); recursivelyBuildStrategy(narrowedOutOfBoundsLayouts, narrowedBestBytes); for (const cand of narrowedDistinctValues.values()) diff --git a/sdk/js-connect/core/base/src/utils/mapping.ts b/sdk/js-connect/core/base/src/utils/mapping.ts index 94af6413e5..fdceb8fa59 100644 --- a/sdk/js-connect/core/base/src/utils/mapping.ts +++ b/sdk/js-connect/core/base/src/utils/mapping.ts @@ -384,7 +384,7 @@ const toMapping = < throw new Error("Invalid mapping: empty"); const definedShape = (shape === undefined) - ? [range(crr[0].length - 1), [crr[0].length - 1]] + ? [range(crr[0]!.length - 1), [crr[0]!.length - 1]] : shape.map(ind => typeof ind === "number" ? [ind] : ind); // store reference to leaf object to unwrap values if all leaves are singletons @@ -396,13 +396,13 @@ const toMapping = < ): any => { const distinctKeys = Array.from(new Set(keyCartesianSet[0]).values()); const keyRows = new Map(distinctKeys.map(key => [key, []])); - for (const [i, key] of keyCartesianSet[0].entries()) + for (const [i, key] of keyCartesianSet[0]!.entries()) keyRows.get(key)!.push(i); // termination case if (keyCartesianSet.length === 1) { const ret = Object.fromEntries(distinctKeys.map(key => - [key, keyRows.get(key)!.map(i => values[i].length === 1 ? values[i][0] : values[i])] + [key, keyRows.get(key)!.map(i => values[i]!.length === 1 ? values[i]![0] : values[i])] )); if (allSingletons) { @@ -420,8 +420,8 @@ const toMapping = < const droppedKeyCol = zip(keyCartesianSet.slice(1)); return Object.fromEntries(distinctKeys.map(key => { const rows = keyRows.get(key)!; - const keyCartesianSubset = zip(rows.map(i => droppedKeyCol[i])); - const valuesSubset = rows.map(i => values[i]); + const keyCartesianSubset = zip(rows.map(i => droppedKeyCol[i]!)); + const valuesSubset = rows.map(i => values[i]!); return [ key, buildMappingRecursively(keyCartesianSubset as CartesianSet, valuesSubset) @@ -441,20 +441,20 @@ const toMapping = < const [keyCartesianSet, leafValues] = definedShape.map(indx => indx.map(col => getCol(col))); - if (keyCartesianSet.length === 0) + if (keyCartesianSet!.length === 0) throw new Error("Invalid shape: empty key set"); - if (leafValues.length === 0) + if (leafValues!.length === 0) throw new Error("Invalid shape: empty value set"); - for (const keyCol of keyCartesianSet) + for (const keyCol of keyCartesianSet!) for (const key of keyCol) if (!isMappableKey(key)) throw new Error(`Invalid key: ${key} in ${keyCol}`); const ret = buildMappingRecursively( keyCartesianSet as CartesianSet, - zip(leafValues) + zip(leafValues!) ); if (allSingletons) diff --git a/sdk/js-connect/package-lock.json b/sdk/js-connect/package-lock.json index 2cd328ca68..04a4f36b38 100644 --- a/sdk/js-connect/package-lock.json +++ b/sdk/js-connect/package-lock.json @@ -32,7 +32,7 @@ }, "core/base": { "name": "@wormhole-foundation/sdk-base", - "version": "0.1.8-beta.10", + "version": "0.0.1", "license": "Apache-2.0", "dependencies": { "@scure/base": "^1.1.3" diff --git a/sdk/js-connect/package.json b/sdk/js-connect/package.json index 1321755581..49c3a3ea0a 100644 --- a/sdk/js-connect/package.json +++ b/sdk/js-connect/package.json @@ -36,11 +36,8 @@ "coverage": "npm run coverage --workspaces --if-present", "clean": "npm run clean --workspaces --if-present", "prettier": "npm run prettier --workspaces --if-present", - "bump:beta": "bump prerelease && npm run bump:beta --workspaces --if-present", - "test": "npm run test --workspaces --if-present", "test-ci": "jest --verbose --config ./jest.config.ts --roots ./__tests__/tilt", - "docs": "typedoc" }, "workspaces": [ diff --git a/sdk/js-connect/tsconfig.json b/sdk/js-connect/tsconfig.json index 1c0e903964..c78a78f86c 100644 --- a/sdk/js-connect/tsconfig.json +++ b/sdk/js-connect/tsconfig.json @@ -15,9 +15,9 @@ // Strict Checks "alwaysStrict": true, "noImplicitAny": true, - "strictNullChecks": false, + "strictNullChecks": true, + "strictPropertyInitialization": true, "useUnknownInCatchVariables": true, - "strictPropertyInitialization": false, "strictFunctionTypes": true, "noImplicitThis": true, "strictBindCallApply": true,