moneyos 0.6.2 → 0.6.3

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to the repo's current `main` branch are documented here.
4
4
 
5
+ ## 0.6.3 - 2026-04-18
6
+
7
+ ### Fixed
8
+
9
+ - `moneyos init` no longer depends on an Arbitrum RPC call to derive the
10
+ default smart-account address; the CLI now reproduces the factory's CREATE2
11
+ derivation offline from frozen verified `MoneyOSAccountV1` creation bytecode.
12
+ - `moneyos init` now backfills and persists the default gasless config on fresh
13
+ init and on already-initialized wallets, and prints both the EOA and
14
+ smart-account addresses so the wallet split is visible before gasless mode is
15
+ enabled.
16
+
5
17
  ## 0.6.2 - 2026-04-16
6
18
 
7
19
  Fixes the broken `npm install -g moneyos` path reported in #114.
package/README.md CHANGED
@@ -134,7 +134,11 @@ moneyos gasless disable
134
134
  moneyos auth unlock
135
135
  ```
136
136
 
137
- On Arbitrum One v1, `moneyos gasless enable` now bakes in the public relay URL, sponsor, and factory-derived smart-account address automatically. Manual overrides still exist through these environment variables:
137
+ On Arbitrum One v1, `moneyos gasless enable` now bakes in a default relay URL, sponsor, and factory-derived smart-account address automatically.
138
+
139
+ Note: the baked relay is currently network-restricted (Tailnet-scoped) while bring-your-own-relay packaging is in progress (see #112). Off-tailnet users running `moneyos gasless enable` with the defaults will see connection failures on the first intent; either skip gasless for now or point `MONEYOS_GASLESS_RELAY_URL` at a relay you operate.
140
+
141
+ Manual overrides still exist through these environment variables:
138
142
 
139
143
  - `MONEYOS_GASLESS_RELAY_URL`
140
144
  - `MONEYOS_GASLESS_ACCOUNT`
@@ -149,15 +153,14 @@ If you already have funds in the owner EOA, the practical flow is:
149
153
  1. have an initialized wallet (`moneyos init` or `moneyos init --key 0x...`) and unlock it with `moneyos auth unlock`
150
154
  2. run `moneyos balance --all` to inspect the owner EOA balance
151
155
  3. run `moneyos gasless enable`, then `moneyos auth unlock`
152
- 4. run `moneyos auth status` to see the active smart-account address
156
+ 4. run `moneyos auth status` to confirm the active smart-account address and executor mode
153
157
  5. fund that smart-account address from the owner EOA or another wallet
154
- 6. run `moneyos balance --all --address <smart-account-address>` to inspect smart-account funds
158
+ 6. run `moneyos balance --all` to inspect both the owner EOA and smart-account balances, or pass `--address <smart-account-address>` if you want only the smart-account view
155
159
  7. retry the gasless send or swap
156
160
 
157
- Note: `moneyos balance` without `--address` still shows the owner EOA balance,
158
- even when gasless mode is active. Use `moneyos auth status` to get the active
159
- smart-account address, then pass that address with `--address` to inspect
160
- smart-account funds.
161
+ Note: once gasless mode is active, `moneyos balance` without `--address`
162
+ shows both owned addresses when the smart account differs from the owner EOA.
163
+ Use `--address` when you want to inspect only one side explicitly.
161
164
 
162
165
  ## SDK
163
166
 
@@ -266,14 +269,16 @@ Published packages:
266
269
 
267
270
  - `moneyos`
268
271
  - `@moneyos/core`
272
+ - `@moneyos/smart-account`
269
273
  - `@moneyos/swap`
270
274
 
271
- `@moneyos/smart-account` exists in this repo but is not published to npm yet.
272
-
273
275
  Current `moneyos` releases no longer bundle swap into the root SDK or CLI. If
274
276
  you want swap from the root CLI, install `moneyos` and then run
275
277
  `moneyos add swap`.
276
278
 
279
+ `moneyos@0.6.0` and `moneyos@0.6.1` are deprecated on npm; a global install
280
+ crashes before printing `--help` (see #114). Use `moneyos@0.6.2` or later.
281
+
277
282
  ## Current wallet model
278
283
 
279
284
  What is landed in code today:
@@ -382,11 +387,12 @@ Built-in chains:
382
387
 
383
388
  Built-in tokens:
384
389
 
385
- - USDC
386
- - USDT
387
- - RYZE
388
- - ETH
389
- - POL
390
+ - ETH (Arbitrum, Ethereum)
391
+ - POL (Polygon)
392
+ - USDC (Arbitrum, Ethereum, Polygon)
393
+ - USDT (Arbitrum, Ethereum, Polygon)
394
+ - WETH (Arbitrum, Ethereum)
395
+ - RYZE (Arbitrum)
390
396
 
391
397
  ## Current validation status
392
398
 
package/dist/cli/index.js CHANGED
@@ -8,6 +8,10 @@ import { fileURLToPath as fileURLToPath3 } from "url";
8
8
 
9
9
  // src/cli/commands/init.ts
10
10
  import { Command } from "commander";
11
+ import {
12
+ deriveDefaultGaslessAccount,
13
+ getGaslessNetworkDefaults
14
+ } from "@moneyos/smart-account";
11
15
  import { generatePrivateKey, privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
12
16
 
13
17
  // src/core/backup-file.ts
@@ -1623,9 +1627,40 @@ var defaultInitCommandDependencies = {
1623
1627
  getSessionTokenPath,
1624
1628
  saveConfig,
1625
1629
  generatePrivateKey,
1630
+ getGaslessNetworkDefaults,
1631
+ deriveDefaultGaslessAccount,
1626
1632
  log: (message) => console.log(message),
1627
1633
  error: (message) => console.error(message)
1628
1634
  };
1635
+ async function resolveInitialGaslessConfig(params, deps) {
1636
+ const defaults = deps.getGaslessNetworkDefaults(params.chainId);
1637
+ const account = params.existingGasless?.account ?? await deps.deriveDefaultGaslessAccount({
1638
+ chainId: params.chainId,
1639
+ owner: params.ownerAddress,
1640
+ rpcUrl: params.rpcUrl
1641
+ });
1642
+ if (!params.existingGasless && !defaults && !account) {
1643
+ return void 0;
1644
+ }
1645
+ return {
1646
+ enabled: params.existingGasless?.enabled ?? false,
1647
+ relayUrl: params.existingGasless?.relayUrl ?? defaults?.relayUrl,
1648
+ sponsor: params.existingGasless?.sponsor ?? defaults?.sponsor,
1649
+ account
1650
+ };
1651
+ }
1652
+ function logWalletSummary(params) {
1653
+ params.deps.log(`EOA: ${params.eoa}`);
1654
+ if (params.gasless?.account) {
1655
+ const suffix = params.gasless.enabled ? " (active gasless wallet)" : " (inactive \u2014 run `moneyos gasless enable` to use)";
1656
+ params.deps.log(`Smart account: ${params.gasless.account}${suffix}`);
1657
+ }
1658
+ params.deps.log(`Wallet: ${params.walletPath}`);
1659
+ params.deps.log(`Config: ${params.deps.getConfigPath()}`);
1660
+ if (params.backupPath) {
1661
+ params.deps.log(`Backup: ${params.backupPath}`);
1662
+ }
1663
+ }
1629
1664
  async function runInitCommand(options, deps = defaultInitCommandDependencies) {
1630
1665
  const existing = deps.loadFileConfig();
1631
1666
  const walletPath = deps.getWalletPath(existing);
@@ -1633,12 +1668,36 @@ async function runInitCommand(options, deps = defaultInitCommandDependencies) {
1633
1668
  const wallet = deps.createWalletStore(walletPath);
1634
1669
  if (wallet.exists() && !options.force) {
1635
1670
  const metadata = await wallet.metadata();
1671
+ const gasless = metadata?.address ? await resolveInitialGaslessConfig(
1672
+ {
1673
+ chainId: existing.chainId ?? 42161,
1674
+ ownerAddress: metadata.address,
1675
+ rpcUrl: existing.rpcUrl,
1676
+ existingGasless: existing.gasless
1677
+ },
1678
+ deps
1679
+ ) : existing.gasless;
1680
+ if (gasless && JSON.stringify(gasless) !== JSON.stringify(existing.gasless)) {
1681
+ deps.saveConfig({
1682
+ chainId: existing.chainId,
1683
+ rpcUrl: existing.rpcUrl,
1684
+ walletPath: existing.walletPath,
1685
+ backupDir: existing.backupDir,
1686
+ gasless
1687
+ });
1688
+ }
1636
1689
  deps.log(`Already initialized.`);
1637
1690
  if (metadata?.address) {
1638
- deps.log(`Address: ${metadata.address}`);
1691
+ logWalletSummary({
1692
+ deps,
1693
+ walletPath,
1694
+ eoa: metadata.address,
1695
+ gasless
1696
+ });
1697
+ } else {
1698
+ deps.log(`Wallet: ${walletPath}`);
1699
+ deps.log(`Config: ${deps.getConfigPath()}`);
1639
1700
  }
1640
- deps.log(`Wallet: ${walletPath}`);
1641
- deps.log(`Config: ${deps.getConfigPath()}`);
1642
1701
  deps.log(`
1643
1702
  To reinitialize, run: moneyos init --force --key <privateKey>`);
1644
1703
  return;
@@ -1653,6 +1712,15 @@ To reinitialize, run: moneyos init --force --key <privateKey>`);
1653
1712
  const account = privateKeyToAccount3(privateKey);
1654
1713
  const chainId = parseChainId(options.chain, existing.chainId ?? 42161);
1655
1714
  const rpcUrl = options.rpc ?? existing.rpcUrl;
1715
+ const gasless = await resolveInitialGaslessConfig(
1716
+ {
1717
+ chainId,
1718
+ ownerAddress: account.address,
1719
+ rpcUrl,
1720
+ existingGasless: existing.gasless
1721
+ },
1722
+ deps
1723
+ );
1656
1724
  const passphrase = await deps.promptHidden("Choose wallet password: ");
1657
1725
  if (passphrase.length < 8) {
1658
1726
  throw new Error("Wallet password must be at least 8 characters long.");
@@ -1673,7 +1741,8 @@ To reinitialize, run: moneyos init --force --key <privateKey>`);
1673
1741
  chainId,
1674
1742
  rpcUrl,
1675
1743
  walletPath: existing.walletPath,
1676
- backupDir: existing.backupDir
1744
+ backupDir: existing.backupDir,
1745
+ gasless
1677
1746
  });
1678
1747
  const backupProvider = deps.createBackupProvider({
1679
1748
  walletPath,
@@ -1681,10 +1750,13 @@ To reinitialize, run: moneyos init --force --key <privateKey>`);
1681
1750
  });
1682
1751
  const backupPath = await backupProvider.exportWallet();
1683
1752
  deps.log(`MoneyOS initialized.`);
1684
- deps.log(`Address: ${account.address}`);
1685
- deps.log(`Wallet: ${walletPath}`);
1686
- deps.log(`Config: ${deps.getConfigPath()}`);
1687
- deps.log(`Backup: ${backupPath}`);
1753
+ logWalletSummary({
1754
+ deps,
1755
+ walletPath,
1756
+ backupPath,
1757
+ eoa: account.address,
1758
+ gasless
1759
+ });
1688
1760
  deps.log(
1689
1761
  `
1690
1762
  Save your wallet password in your password manager of choice. MoneyOS does not store or sync it for you.`
@@ -1951,8 +2023,8 @@ async function connectLocalSession(options = {}) {
1951
2023
 
1952
2024
  // src/cli/gasless.ts
1953
2025
  import {
1954
- deriveDefaultGaslessAccount,
1955
- getGaslessNetworkDefaults
2026
+ deriveDefaultGaslessAccount as deriveDefaultGaslessAccount2,
2027
+ getGaslessNetworkDefaults as getGaslessNetworkDefaults2
1956
2028
  } from "@moneyos/smart-account";
1957
2029
  var GASLESS_ENABLED_ENV = "MONEYOS_GASLESS_ENABLED";
1958
2030
  var GASLESS_RELAY_URL_ENV = "MONEYOS_GASLESS_RELAY_URL";
@@ -1975,7 +2047,7 @@ function isGaslessEnabled(config) {
1975
2047
  return config.gasless?.enabled === true;
1976
2048
  }
1977
2049
  function getGaslessRequiredEnvPresence(config) {
1978
- const defaults = config.chainId ? getGaslessNetworkDefaults(config.chainId) : void 0;
2050
+ const defaults = config.chainId ? getGaslessNetworkDefaults2(config.chainId) : void 0;
1979
2051
  return {
1980
2052
  relayUrl: Boolean(
1981
2053
  process.env[GASLESS_RELAY_URL_ENV] ?? config.gasless?.relayUrl ?? defaults?.relayUrl
@@ -1991,12 +2063,12 @@ async function resolveGaslessExecutionConfig(config, options = {}) {
1991
2063
  return void 0;
1992
2064
  }
1993
2065
  const chainId = options.chainId ?? config.chainId;
1994
- const defaults = chainId ? getGaslessNetworkDefaults(chainId) : void 0;
2066
+ const defaults = chainId ? getGaslessNetworkDefaults2(chainId) : void 0;
1995
2067
  const relayUrl = process.env[GASLESS_RELAY_URL_ENV] ?? config.gasless?.relayUrl ?? defaults?.relayUrl;
1996
2068
  const sponsor = process.env[GASLESS_SPONSOR_ENV] ?? config.gasless?.sponsor ?? defaults?.sponsor;
1997
2069
  let account = process.env[GASLESS_ACCOUNT_ENV] ?? config.gasless?.account;
1998
2070
  if (!account && chainId && options.ownerAddress) {
1999
- account = await deriveDefaultGaslessAccount({
2071
+ account = await deriveDefaultGaslessAccount2({
2000
2072
  chainId,
2001
2073
  owner: options.ownerAddress,
2002
2074
  rpcUrl: options.rpcUrl
@@ -2823,7 +2895,7 @@ contactCommand.command("remove").description("Remove a saved contact").argument(
2823
2895
 
2824
2896
  // src/cli/commands/gasless.ts
2825
2897
  import { Command as Command8 } from "commander";
2826
- import { getGaslessNetworkDefaults as getGaslessNetworkDefaults2 } from "@moneyos/smart-account";
2898
+ import { getGaslessNetworkDefaults as getGaslessNetworkDefaults3 } from "@moneyos/smart-account";
2827
2899
  function formatEnabled(enabled) {
2828
2900
  return enabled ? "enabled" : "disabled";
2829
2901
  }
@@ -2853,7 +2925,7 @@ async function runGaslessToggle(enabled) {
2853
2925
  }
2854
2926
  };
2855
2927
  const ownerAddress = (await loadCliAddress(config)).address;
2856
- const defaults = config.chainId ? getGaslessNetworkDefaults2(config.chainId) : void 0;
2928
+ const defaults = config.chainId ? getGaslessNetworkDefaults3(config.chainId) : void 0;
2857
2929
  const derived = ownerAddress ? await resolveGaslessExecutionConfig(enabledConfig, {
2858
2930
  ownerAddress,
2859
2931
  chainId: config.chainId,