@alchemy/cli 0.6.1 → 0.6.3-alpha.6
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/README.md +49 -61
- package/dist/auth-I5WFLU46.js +16 -0
- package/dist/{auth-S4DTOWW3.js → auth-JGON2JU6.js} +10 -8
- package/dist/{chunk-NBDWF4ZQ.js → chunk-A6L3WCJN.js} +32 -22
- package/dist/{chunk-BAAQ7ELR.js → chunk-B3R6PRAL.js} +59 -4
- package/dist/{chunk-FFMNT74F.js → chunk-HSKKIATB.js} +125 -76
- package/dist/{chunk-KDMIWPZH.js → chunk-HYCRHNPX.js} +1 -1
- package/dist/chunk-MUT4TFQ5.js +64 -0
- package/dist/{chunk-7GD5HACA.js → chunk-NSBL7TUF.js} +3 -3
- package/dist/{chunk-UMKDYHMO.js → chunk-NT3G6BKD.js} +54 -99
- package/dist/{chunk-ATX65U7J.js → chunk-PKAN5FKD.js} +570 -41
- package/dist/{chunk-56ZVYB4G.js → chunk-QEDAULQ2.js} +263 -222
- package/dist/errors-3CNFGAXT.js +54 -0
- package/dist/index.js +6670 -2158
- package/dist/{interactive-QJ4REXWB.js → interactive-OSVYTHBP.js} +56 -61
- package/dist/{onboarding-3WIM6PVV.js → onboarding-EBOY4QWF.js} +14 -11
- package/dist/resolve-X7HLVLGA.js +50 -0
- package/package.json +12 -3
- package/scripts/postinstall.cjs +69 -1
- package/dist/auth-QB3BA7AN.js +0 -17
- package/dist/chunk-JQRGILIS.js +0 -53
- package/dist/chunk-T5Z2GJUX.js +0 -331
- package/dist/credential-storage-T6FFW7DG.js +0 -14
- package/dist/resolve-HXKHDOJZ.js +0 -31
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
} from "./chunk-JQRGILIS.js";
|
|
6
|
-
import {
|
|
4
|
+
configDir,
|
|
7
5
|
load,
|
|
8
6
|
save
|
|
9
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-B3R6PRAL.js";
|
|
10
8
|
import {
|
|
11
9
|
CLIError,
|
|
12
10
|
ErrorCode,
|
|
@@ -31,10 +29,10 @@ import {
|
|
|
31
29
|
parseBaseURLOverride,
|
|
32
30
|
redactSensitiveText,
|
|
33
31
|
verbose
|
|
34
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-QEDAULQ2.js";
|
|
35
33
|
|
|
36
34
|
// src/lib/resolve.ts
|
|
37
|
-
import { readFileSync } from "fs";
|
|
35
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
38
36
|
|
|
39
37
|
// src/lib/client.ts
|
|
40
38
|
var Client = class _Client {
|
|
@@ -58,12 +56,12 @@ var Client = class _Client {
|
|
|
58
56
|
parsed = new URL(`https://${hostname}`);
|
|
59
57
|
} catch {
|
|
60
58
|
throw errInvalidArgs(
|
|
61
|
-
`Unknown network '${network}'. Run 'alchemy network list' to see available networks.`
|
|
59
|
+
`Unknown network '${network}'. Run 'alchemy evm network list' to see available networks.`
|
|
62
60
|
);
|
|
63
61
|
}
|
|
64
62
|
if (!parsed.hostname.endsWith(`.g.${domain}`)) {
|
|
65
63
|
throw errInvalidArgs(
|
|
66
|
-
`Unknown network '${network}'. Run 'alchemy network list' to see available networks.`
|
|
64
|
+
`Unknown network '${network}'. Run 'alchemy evm network list' to see available networks.`
|
|
67
65
|
);
|
|
68
66
|
}
|
|
69
67
|
}
|
|
@@ -413,6 +411,7 @@ var X402Client = class _X402Client {
|
|
|
413
411
|
};
|
|
414
412
|
|
|
415
413
|
// src/lib/admin-client.ts
|
|
414
|
+
var STAGING_ADMIN_API_HOST = "admin-api.alchemypreview.com";
|
|
416
415
|
var AdminClient = class _AdminClient {
|
|
417
416
|
static get ADMIN_API_HOST() {
|
|
418
417
|
return `admin-api.${getBaseDomain()}`;
|
|
@@ -448,7 +447,9 @@ var AdminClient = class _AdminClient {
|
|
|
448
447
|
return isLocalhost(hostname);
|
|
449
448
|
}
|
|
450
449
|
baseURLOverride() {
|
|
451
|
-
return parseBaseURLOverride(_AdminClient.ADMIN_API_BASE_URL_ENV
|
|
450
|
+
return parseBaseURLOverride(_AdminClient.ADMIN_API_BASE_URL_ENV, {
|
|
451
|
+
allowedHostnames: [STAGING_ADMIN_API_HOST]
|
|
452
|
+
});
|
|
452
453
|
}
|
|
453
454
|
validateAccessKey(accessKey) {
|
|
454
455
|
if (!accessKey.trim() || /\s/.test(accessKey)) {
|
|
@@ -592,9 +593,429 @@ var AdminClient = class _AdminClient {
|
|
|
592
593
|
}
|
|
593
594
|
};
|
|
594
595
|
|
|
596
|
+
// src/lib/networks.ts
|
|
597
|
+
var TESTNET_TOKEN_RE = /(testnet|sepolia|holesky|hoodi|devnet|minato|amoy|fuji|saigon|cardona|aeneid|curtis|chiado|cassiopeia|blaze|ropsten|signet|mocha|fam|bepolia)$/i;
|
|
598
|
+
var FAMILY_ALIASES = {
|
|
599
|
+
arb: "Arbitrum",
|
|
600
|
+
arbnova: "Arbitrum Nova",
|
|
601
|
+
avax: "Avalanche",
|
|
602
|
+
bnb: "BNB Smart Chain",
|
|
603
|
+
eth: "Ethereum",
|
|
604
|
+
opt: "OP Mainnet",
|
|
605
|
+
polygonzkevm: "Polygon zkEVM"
|
|
606
|
+
};
|
|
607
|
+
var NAME_ALIASES = {
|
|
608
|
+
arb: "Arbitrum",
|
|
609
|
+
avax: "Avalanche",
|
|
610
|
+
bnb: "BNB",
|
|
611
|
+
eth: "Ethereum",
|
|
612
|
+
opbnb: "opBNB",
|
|
613
|
+
opt: "OP Mainnet",
|
|
614
|
+
sui: "SUI",
|
|
615
|
+
xmtp: "XMTP",
|
|
616
|
+
zksync: "ZKsync"
|
|
617
|
+
};
|
|
618
|
+
var RPC_NETWORK_IDS = [
|
|
619
|
+
"abstract-mainnet",
|
|
620
|
+
"abstract-testnet",
|
|
621
|
+
"adi-mainnet",
|
|
622
|
+
"adi-testnet",
|
|
623
|
+
"alchemy-internal",
|
|
624
|
+
"alchemy-sepolia",
|
|
625
|
+
"alchemyarb-fam",
|
|
626
|
+
"alchemyarb-sepolia",
|
|
627
|
+
"alterscope-mainnet",
|
|
628
|
+
"anime-mainnet",
|
|
629
|
+
"anime-sepolia",
|
|
630
|
+
"apechain-curtis",
|
|
631
|
+
"apechain-mainnet",
|
|
632
|
+
"aptos-mainnet",
|
|
633
|
+
"aptos-testnet",
|
|
634
|
+
"arb-mainnet",
|
|
635
|
+
"arb-sepolia",
|
|
636
|
+
"arbnova-mainnet",
|
|
637
|
+
"arc-testnet",
|
|
638
|
+
"astar-mainnet",
|
|
639
|
+
"avax-fuji",
|
|
640
|
+
"avax-mainnet",
|
|
641
|
+
"base-mainnet",
|
|
642
|
+
"base-sepolia",
|
|
643
|
+
"berachain-bepolia",
|
|
644
|
+
"berachain-mainnet",
|
|
645
|
+
"bitcoin-mainnet",
|
|
646
|
+
"bitcoin-signet",
|
|
647
|
+
"bitcoin-testnet",
|
|
648
|
+
"blast-mainnet",
|
|
649
|
+
"blast-sepolia",
|
|
650
|
+
"bnb-mainnet",
|
|
651
|
+
"bnb-testnet",
|
|
652
|
+
"bob-mainnet",
|
|
653
|
+
"bob-sepolia",
|
|
654
|
+
"boba-mainnet",
|
|
655
|
+
"boba-sepolia",
|
|
656
|
+
"botanix-mainnet",
|
|
657
|
+
"botanix-testnet",
|
|
658
|
+
"celestiabridge-mainnet",
|
|
659
|
+
"celestiabridge-mocha",
|
|
660
|
+
"celo-mainnet",
|
|
661
|
+
"celo-sepolia",
|
|
662
|
+
"citrea-mainnet",
|
|
663
|
+
"citrea-testnet",
|
|
664
|
+
"clankermon-mainnet",
|
|
665
|
+
"commons-mainnet",
|
|
666
|
+
"crossfi-mainnet",
|
|
667
|
+
"crossfi-testnet",
|
|
668
|
+
"degen-mainnet",
|
|
669
|
+
"degen-sepolia",
|
|
670
|
+
"earnm-mainnet",
|
|
671
|
+
"earnm-sepolia",
|
|
672
|
+
"edge-mainnet",
|
|
673
|
+
"edge-testnet",
|
|
674
|
+
"eth-holesky",
|
|
675
|
+
"eth-holeskybeacon",
|
|
676
|
+
"eth-hoodi",
|
|
677
|
+
"eth-hoodibeacon",
|
|
678
|
+
"eth-mainnet",
|
|
679
|
+
"eth-mainnetbeacon",
|
|
680
|
+
"eth-sepolia",
|
|
681
|
+
"eth-sepoliabeacon",
|
|
682
|
+
"flow-mainnet",
|
|
683
|
+
"flow-testnet",
|
|
684
|
+
"frax-hoodi",
|
|
685
|
+
"frax-mainnet",
|
|
686
|
+
"galactica-cassiopeia",
|
|
687
|
+
"galactica-mainnet",
|
|
688
|
+
"gensyn-mainnet",
|
|
689
|
+
"gensyn-testnet",
|
|
690
|
+
"gnosis-chiado",
|
|
691
|
+
"gnosis-mainnet",
|
|
692
|
+
"humanity-mainnet",
|
|
693
|
+
"humanity-testnet",
|
|
694
|
+
"hyperliquid-mainnet",
|
|
695
|
+
"hyperliquid-testnet",
|
|
696
|
+
"ink-mainnet",
|
|
697
|
+
"ink-sepolia",
|
|
698
|
+
"lens-mainnet",
|
|
699
|
+
"lens-sepolia",
|
|
700
|
+
"linea-mainnet",
|
|
701
|
+
"linea-sepolia",
|
|
702
|
+
"mantle-mainnet",
|
|
703
|
+
"mantle-sepolia",
|
|
704
|
+
"megaeth-mainnet",
|
|
705
|
+
"megaeth-testnet",
|
|
706
|
+
"metis-mainnet",
|
|
707
|
+
"mode-mainnet",
|
|
708
|
+
"mode-sepolia",
|
|
709
|
+
"monad-mainnet",
|
|
710
|
+
"monad-testnet",
|
|
711
|
+
"moonbeam-mainnet",
|
|
712
|
+
"mythos-mainnet",
|
|
713
|
+
"opbnb-mainnet",
|
|
714
|
+
"opbnb-testnet",
|
|
715
|
+
"openloot-sepolia",
|
|
716
|
+
"opt-mainnet",
|
|
717
|
+
"opt-sepolia",
|
|
718
|
+
"plasma-mainnet",
|
|
719
|
+
"plasma-testnet",
|
|
720
|
+
"polygon-amoy",
|
|
721
|
+
"polygon-mainnet",
|
|
722
|
+
"polygonzkevm-cardona",
|
|
723
|
+
"polygonzkevm-mainnet",
|
|
724
|
+
"polynomial-mainnet",
|
|
725
|
+
"polynomial-sepolia",
|
|
726
|
+
"race-mainnet",
|
|
727
|
+
"race-sepolia",
|
|
728
|
+
"risa-testnet",
|
|
729
|
+
"rise-testnet",
|
|
730
|
+
"ronin-mainnet",
|
|
731
|
+
"ronin-saigon",
|
|
732
|
+
"rootstock-mainnet",
|
|
733
|
+
"rootstock-testnet",
|
|
734
|
+
"scroll-mainnet",
|
|
735
|
+
"scroll-sepolia",
|
|
736
|
+
"sei-mainnet",
|
|
737
|
+
"sei-testnet",
|
|
738
|
+
"settlus-mainnet",
|
|
739
|
+
"settlus-septestnet",
|
|
740
|
+
"shape-mainnet",
|
|
741
|
+
"shape-sepolia",
|
|
742
|
+
"solana-devnet",
|
|
743
|
+
"solana-mainnet",
|
|
744
|
+
"soneium-mainnet",
|
|
745
|
+
"soneium-minato",
|
|
746
|
+
"sonic-blaze",
|
|
747
|
+
"sonic-mainnet",
|
|
748
|
+
"sonic-testnet",
|
|
749
|
+
"stable-mainnet",
|
|
750
|
+
"stable-testnet",
|
|
751
|
+
"standard-mainnet",
|
|
752
|
+
"starknet-mainnet",
|
|
753
|
+
"starknet-sepolia",
|
|
754
|
+
"story-aeneid",
|
|
755
|
+
"story-mainnet",
|
|
756
|
+
"sui-mainnet",
|
|
757
|
+
"sui-testnet",
|
|
758
|
+
"superseed-mainnet",
|
|
759
|
+
"superseed-sepolia",
|
|
760
|
+
"synd-mainnet",
|
|
761
|
+
"syndicate-manchego",
|
|
762
|
+
"tea-sepolia",
|
|
763
|
+
"tempo-testnet",
|
|
764
|
+
"tron-mainnet",
|
|
765
|
+
"tron-testnet",
|
|
766
|
+
"unichain-mainnet",
|
|
767
|
+
"unichain-sepolia",
|
|
768
|
+
"unite-mainnet",
|
|
769
|
+
"unite-testnet",
|
|
770
|
+
"worldchain-mainnet",
|
|
771
|
+
"worldchain-sepolia",
|
|
772
|
+
"worldl3-devnet",
|
|
773
|
+
"worldmobile-devnet",
|
|
774
|
+
"worldmobile-testnet",
|
|
775
|
+
"worldmobilechain-mainnet",
|
|
776
|
+
"xmtp-mainnet",
|
|
777
|
+
"xmtp-ropsten",
|
|
778
|
+
"xprotocol-mainnet",
|
|
779
|
+
"zetachain-mainnet",
|
|
780
|
+
"zetachain-testnet",
|
|
781
|
+
"zksync-mainnet",
|
|
782
|
+
"zksync-sepolia",
|
|
783
|
+
"zora-mainnet",
|
|
784
|
+
"zora-sepolia"
|
|
785
|
+
];
|
|
786
|
+
function isTestnetNetwork(id) {
|
|
787
|
+
return TESTNET_TOKEN_RE.test(id);
|
|
788
|
+
}
|
|
789
|
+
function tokenToName(token) {
|
|
790
|
+
const alias = NAME_ALIASES[token];
|
|
791
|
+
if (alias) return alias;
|
|
792
|
+
return token.charAt(0).toUpperCase() + token.slice(1);
|
|
793
|
+
}
|
|
794
|
+
function toFamily(id) {
|
|
795
|
+
const [head] = id.split("-");
|
|
796
|
+
return FAMILY_ALIASES[head] ?? tokenToName(head);
|
|
797
|
+
}
|
|
798
|
+
function toDisplayName(id) {
|
|
799
|
+
return id.split("-").map((part) => tokenToName(part)).join(" ");
|
|
800
|
+
}
|
|
801
|
+
function toHttpsUrlTemplate(id) {
|
|
802
|
+
const domain = getBaseDomain();
|
|
803
|
+
if (id === "starknet-mainnet" || id === "starknet-sepolia") {
|
|
804
|
+
return `https://${id}.g.${domain}/starknet/version/rpc/v0_10/{apiKey}`;
|
|
805
|
+
}
|
|
806
|
+
return `https://${id}.g.${domain}/v2/{apiKey}`;
|
|
807
|
+
}
|
|
808
|
+
function getRPCNetworks() {
|
|
809
|
+
return RPC_NETWORK_IDS.map((id) => ({
|
|
810
|
+
id,
|
|
811
|
+
name: toDisplayName(id),
|
|
812
|
+
family: toFamily(id),
|
|
813
|
+
isTestnet: isTestnetNetwork(id),
|
|
814
|
+
httpsUrlTemplate: toHttpsUrlTemplate(id)
|
|
815
|
+
}));
|
|
816
|
+
}
|
|
817
|
+
function getRPCNetworkIds() {
|
|
818
|
+
return [...RPC_NETWORK_IDS];
|
|
819
|
+
}
|
|
820
|
+
var NATIVE_TOKEN_SYMBOLS = {
|
|
821
|
+
eth: "ETH",
|
|
822
|
+
arb: "ETH",
|
|
823
|
+
arbnova: "ETH",
|
|
824
|
+
opt: "ETH",
|
|
825
|
+
base: "ETH",
|
|
826
|
+
zksync: "ETH",
|
|
827
|
+
scroll: "ETH",
|
|
828
|
+
blast: "ETH",
|
|
829
|
+
linea: "ETH",
|
|
830
|
+
zora: "ETH",
|
|
831
|
+
shape: "ETH",
|
|
832
|
+
polygon: "POL",
|
|
833
|
+
polygonzkevm: "ETH",
|
|
834
|
+
bnb: "BNB",
|
|
835
|
+
opbnb: "BNB",
|
|
836
|
+
avax: "AVAX",
|
|
837
|
+
solana: "SOL",
|
|
838
|
+
starknet: "ETH",
|
|
839
|
+
fantom: "FTM",
|
|
840
|
+
metis: "METIS",
|
|
841
|
+
mantle: "MNT",
|
|
842
|
+
celo: "CELO",
|
|
843
|
+
gnosis: "xDAI",
|
|
844
|
+
frax: "frxETH",
|
|
845
|
+
worldchain: "ETH",
|
|
846
|
+
berachain: "BERA",
|
|
847
|
+
flow: "FLOW",
|
|
848
|
+
rootstock: "RBTC",
|
|
849
|
+
zetachain: "ZETA",
|
|
850
|
+
sui: "SUI"
|
|
851
|
+
};
|
|
852
|
+
function isSolanaNetwork(networkId) {
|
|
853
|
+
return networkId.startsWith("solana-");
|
|
854
|
+
}
|
|
855
|
+
function nativeTokenSymbol(networkId) {
|
|
856
|
+
const prefix = networkId.replace(/-(mainnet|testnet|sepolia|holesky|hoodi|devnet|amoy|fuji|cardona|saigon|chiado|signet|mocha|blaze|curtis|bepolia).*$/, "");
|
|
857
|
+
return NATIVE_TOKEN_SYMBOLS[prefix] ?? "ETH";
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// src/lib/wallet-session.ts
|
|
861
|
+
import { generateKeyPairSync, randomUUID } from "crypto";
|
|
862
|
+
import { readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from "fs";
|
|
863
|
+
import { join, dirname } from "path";
|
|
864
|
+
import { z } from "zod";
|
|
865
|
+
var SESSION_FILE = "wallet-session.json";
|
|
866
|
+
var SESSION_TTL_DAYS = 7;
|
|
867
|
+
var SESSION_ENVELOPE_VERSION = "v1";
|
|
868
|
+
var walletSessionCapabilitiesSchema = z.object({
|
|
869
|
+
"evm.signMessage": z.boolean().optional(),
|
|
870
|
+
"evm.signTypedData": z.boolean().optional(),
|
|
871
|
+
"evm.signAuthorization": z.boolean().optional(),
|
|
872
|
+
"solana.signTransaction": z.boolean().optional()
|
|
873
|
+
}).strict();
|
|
874
|
+
var walletSessionEnvironmentSchema = z.object({
|
|
875
|
+
platform: z.string().min(1),
|
|
876
|
+
arch: z.string().min(1),
|
|
877
|
+
nodeVersion: z.string().min(1),
|
|
878
|
+
interactive: z.boolean()
|
|
879
|
+
}).strict();
|
|
880
|
+
var walletSessionSchema = z.object({
|
|
881
|
+
sessionId: z.string().uuid(),
|
|
882
|
+
status: z.enum(["pending", "approved", "revoked", "expired"]),
|
|
883
|
+
createdAt: z.string().datetime(),
|
|
884
|
+
expiresAt: z.string().datetime(),
|
|
885
|
+
envelopeVersion: z.string().min(1),
|
|
886
|
+
publicKeyJwk: z.object({}).passthrough(),
|
|
887
|
+
privateKeyPem: z.string().min(1),
|
|
888
|
+
privyAppId: z.string().min(1).optional(),
|
|
889
|
+
walletId: z.string().min(1).optional(),
|
|
890
|
+
evmWalletId: z.string().min(1).optional(),
|
|
891
|
+
evmAddress: z.string().min(1).optional(),
|
|
892
|
+
solanaWalletId: z.string().min(1).optional(),
|
|
893
|
+
solanaAddress: z.string().min(1).optional(),
|
|
894
|
+
privyKeyQuorumId: z.string().min(1).optional(),
|
|
895
|
+
privySignerId: z.string().min(1).optional(),
|
|
896
|
+
chainType: z.string().min(1).optional(),
|
|
897
|
+
backendBaseUrl: z.string().min(1).optional(),
|
|
898
|
+
environment: walletSessionEnvironmentSchema.optional(),
|
|
899
|
+
capabilities: walletSessionCapabilitiesSchema.optional()
|
|
900
|
+
}).strict();
|
|
901
|
+
function sessionPath() {
|
|
902
|
+
return join(configDir(), SESSION_FILE);
|
|
903
|
+
}
|
|
904
|
+
function parseStoredSession(value) {
|
|
905
|
+
const parsed = walletSessionSchema.safeParse(value);
|
|
906
|
+
if (!parsed.success) return null;
|
|
907
|
+
return parsed.data;
|
|
908
|
+
}
|
|
909
|
+
function loadStoredSessionFromPath(path) {
|
|
910
|
+
if (!existsSync(path)) return null;
|
|
911
|
+
try {
|
|
912
|
+
return parseStoredSession(JSON.parse(readFileSync(path, "utf-8")));
|
|
913
|
+
} catch {
|
|
914
|
+
return null;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
function isExpired(session) {
|
|
918
|
+
const expiresAt = new Date(session.expiresAt);
|
|
919
|
+
return !Number.isNaN(expiresAt.getTime()) && expiresAt <= /* @__PURE__ */ new Date();
|
|
920
|
+
}
|
|
921
|
+
function createFileWalletSessionStore(path = sessionPath()) {
|
|
922
|
+
return {
|
|
923
|
+
load() {
|
|
924
|
+
const session = loadStoredSessionFromPath(path);
|
|
925
|
+
if (!session) return null;
|
|
926
|
+
if (session.status === "revoked") return null;
|
|
927
|
+
if (isExpired(session)) return null;
|
|
928
|
+
return session;
|
|
929
|
+
},
|
|
930
|
+
loadRaw() {
|
|
931
|
+
return loadStoredSessionFromPath(path);
|
|
932
|
+
},
|
|
933
|
+
save(session) {
|
|
934
|
+
mkdirSync(dirname(path), { recursive: true, mode: 493 });
|
|
935
|
+
writeFileSync(path, JSON.stringify(session, null, 2) + "\n", { mode: 384 });
|
|
936
|
+
},
|
|
937
|
+
clear() {
|
|
938
|
+
if (!existsSync(path)) return false;
|
|
939
|
+
try {
|
|
940
|
+
rmSync(path, { force: true });
|
|
941
|
+
return true;
|
|
942
|
+
} catch {
|
|
943
|
+
return false;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
var walletSessionStore = null;
|
|
949
|
+
function getWalletSessionStore() {
|
|
950
|
+
if (!walletSessionStore) {
|
|
951
|
+
walletSessionStore = createFileWalletSessionStore();
|
|
952
|
+
}
|
|
953
|
+
return walletSessionStore;
|
|
954
|
+
}
|
|
955
|
+
function generateP256Keypair() {
|
|
956
|
+
const { publicKey, privateKey } = generateKeyPairSync("ec", {
|
|
957
|
+
namedCurve: "P-256"
|
|
958
|
+
});
|
|
959
|
+
const publicKeyJwk = publicKey.export({ format: "jwk" });
|
|
960
|
+
const privateKeyPem = privateKey.export({
|
|
961
|
+
type: "pkcs8",
|
|
962
|
+
format: "pem"
|
|
963
|
+
});
|
|
964
|
+
return { publicKeyJwk, privateKeyPem };
|
|
965
|
+
}
|
|
966
|
+
function createPendingSession() {
|
|
967
|
+
const keypair = generateP256Keypair();
|
|
968
|
+
const now = /* @__PURE__ */ new Date();
|
|
969
|
+
const expiresAt = new Date(now.getTime() + SESSION_TTL_DAYS * 24 * 60 * 60 * 1e3);
|
|
970
|
+
const session = {
|
|
971
|
+
sessionId: randomUUID(),
|
|
972
|
+
status: "pending",
|
|
973
|
+
createdAt: now.toISOString(),
|
|
974
|
+
expiresAt: expiresAt.toISOString(),
|
|
975
|
+
envelopeVersion: SESSION_ENVELOPE_VERSION,
|
|
976
|
+
publicKeyJwk: keypair.publicKeyJwk,
|
|
977
|
+
privateKeyPem: keypair.privateKeyPem
|
|
978
|
+
};
|
|
979
|
+
saveSession(session);
|
|
980
|
+
return session;
|
|
981
|
+
}
|
|
982
|
+
function loadSession() {
|
|
983
|
+
return getWalletSessionStore().load();
|
|
984
|
+
}
|
|
985
|
+
function loadStoredSession() {
|
|
986
|
+
const store = getWalletSessionStore();
|
|
987
|
+
if (store.loadRaw) {
|
|
988
|
+
return store.loadRaw();
|
|
989
|
+
}
|
|
990
|
+
return store.load();
|
|
991
|
+
}
|
|
992
|
+
function saveSession(session) {
|
|
993
|
+
getWalletSessionStore().save(session);
|
|
994
|
+
}
|
|
995
|
+
function updateSession(updates) {
|
|
996
|
+
const session = loadSession();
|
|
997
|
+
if (!session) return null;
|
|
998
|
+
const updated = { ...session, ...updates };
|
|
999
|
+
saveSession(updated);
|
|
1000
|
+
return updated;
|
|
1001
|
+
}
|
|
1002
|
+
function clearSession() {
|
|
1003
|
+
return getWalletSessionStore().clear();
|
|
1004
|
+
}
|
|
1005
|
+
function isSessionValid(session) {
|
|
1006
|
+
if (session.status !== "approved") return false;
|
|
1007
|
+
const expiresAt = new Date(session.expiresAt);
|
|
1008
|
+
if (Number.isNaN(expiresAt.getTime())) return false;
|
|
1009
|
+
return expiresAt > /* @__PURE__ */ new Date();
|
|
1010
|
+
}
|
|
1011
|
+
|
|
595
1012
|
// src/lib/resolve.ts
|
|
1013
|
+
function getCommandOptions(program) {
|
|
1014
|
+
const commandWithGlobals = program;
|
|
1015
|
+
return commandWithGlobals.optsWithGlobals?.() ?? program.opts();
|
|
1016
|
+
}
|
|
596
1017
|
function resolveAPIKey(program, cfg) {
|
|
597
|
-
const opts = program
|
|
1018
|
+
const opts = getCommandOptions(program);
|
|
598
1019
|
if (opts.apiKey) return opts.apiKey;
|
|
599
1020
|
if (process.env.ALCHEMY_API_KEY) return process.env.ALCHEMY_API_KEY;
|
|
600
1021
|
const config = cfg ?? load();
|
|
@@ -602,40 +1023,52 @@ function resolveAPIKey(program, cfg) {
|
|
|
602
1023
|
if (config.app?.apiKey) return config.app.apiKey;
|
|
603
1024
|
return void 0;
|
|
604
1025
|
}
|
|
605
|
-
function resolveAccessKey(
|
|
606
|
-
const opts = program.opts();
|
|
607
|
-
if (opts.accessKey) return opts.accessKey;
|
|
1026
|
+
function resolveAccessKey(_program, cfg) {
|
|
608
1027
|
if (process.env.ALCHEMY_ACCESS_KEY) return process.env.ALCHEMY_ACCESS_KEY;
|
|
609
1028
|
const config = cfg ?? load();
|
|
610
1029
|
if (config.access_key) return config.access_key;
|
|
611
1030
|
return void 0;
|
|
612
1031
|
}
|
|
613
1032
|
function resolveNetwork(program, cfg, defaultNetwork) {
|
|
614
|
-
const opts = program
|
|
1033
|
+
const opts = getCommandOptions(program);
|
|
615
1034
|
if (opts.network) return opts.network;
|
|
616
1035
|
if (process.env.ALCHEMY_NETWORK) return process.env.ALCHEMY_NETWORK;
|
|
617
1036
|
const config = cfg ?? load();
|
|
618
1037
|
if (config.network) return config.network;
|
|
619
1038
|
return defaultNetwork ?? "eth-mainnet";
|
|
620
1039
|
}
|
|
1040
|
+
function resolveSolanaNetwork(program, cfg) {
|
|
1041
|
+
const opts = getCommandOptions(program);
|
|
1042
|
+
if (opts.network) {
|
|
1043
|
+
if (!isSolanaNetwork(opts.network)) {
|
|
1044
|
+
throw errInvalidArgs(
|
|
1045
|
+
`Network '${opts.network}' is not a Solana network. Use a solana-* network with the solana namespace.`
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
return opts.network;
|
|
1049
|
+
}
|
|
1050
|
+
if (process.env.ALCHEMY_NETWORK) {
|
|
1051
|
+
if (!isSolanaNetwork(process.env.ALCHEMY_NETWORK)) {
|
|
1052
|
+
throw errInvalidArgs(
|
|
1053
|
+
`ALCHEMY_NETWORK='${process.env.ALCHEMY_NETWORK}' is not a Solana network. Use a solana-* network with the solana namespace.`
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
return process.env.ALCHEMY_NETWORK;
|
|
1057
|
+
}
|
|
1058
|
+
const config = cfg ?? load();
|
|
1059
|
+
if (config.network && isSolanaNetwork(config.network)) {
|
|
1060
|
+
return config.network;
|
|
1061
|
+
}
|
|
1062
|
+
return "solana-mainnet";
|
|
1063
|
+
}
|
|
621
1064
|
function resolveAppId(program, cfg) {
|
|
622
|
-
const opts = program
|
|
1065
|
+
const opts = getCommandOptions(program);
|
|
623
1066
|
if (opts.appId) return opts.appId;
|
|
624
1067
|
const config = cfg ?? load();
|
|
625
1068
|
if (config.app?.id) return config.app.id;
|
|
626
1069
|
return void 0;
|
|
627
1070
|
}
|
|
628
|
-
|
|
629
|
-
const creds = await getCredentials();
|
|
630
|
-
if (creds?.auth_token?.trim()) {
|
|
631
|
-
if (creds.auth_token_expires_at) {
|
|
632
|
-
const expiry = new Date(creds.auth_token_expires_at);
|
|
633
|
-
if (!Number.isNaN(expiry.getTime()) && expiry <= /* @__PURE__ */ new Date()) {
|
|
634
|
-
return void 0;
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
return creds.auth_token;
|
|
638
|
-
}
|
|
1071
|
+
function resolveAuthToken(cfg) {
|
|
639
1072
|
const config = cfg ?? load();
|
|
640
1073
|
if (!config.auth_token?.trim()) return void 0;
|
|
641
1074
|
if (config.auth_token_expires_at) {
|
|
@@ -646,16 +1079,16 @@ async function resolveAuthToken(cfg) {
|
|
|
646
1079
|
}
|
|
647
1080
|
return config.auth_token;
|
|
648
1081
|
}
|
|
649
|
-
|
|
1082
|
+
function adminClientFromFlags(program) {
|
|
650
1083
|
const cfg = load();
|
|
651
1084
|
const accessKey = resolveAccessKey(program, cfg);
|
|
652
1085
|
if (accessKey) return new AdminClient(accessKey);
|
|
653
|
-
const authToken =
|
|
1086
|
+
const authToken = resolveAuthToken(cfg);
|
|
654
1087
|
if (authToken) return new AdminClient({ type: "auth_token", token: authToken });
|
|
655
1088
|
throw errAccessKeyRequired();
|
|
656
1089
|
}
|
|
657
1090
|
function resolveX402(program, cfg) {
|
|
658
|
-
const opts = program
|
|
1091
|
+
const opts = getCommandOptions(program);
|
|
659
1092
|
if (opts.x402) return true;
|
|
660
1093
|
const config = cfg ?? load();
|
|
661
1094
|
return config.x402 === true;
|
|
@@ -668,29 +1101,97 @@ function resolveX402Client(program) {
|
|
|
668
1101
|
return new X402Client(walletKey, resolveNetwork(program, cfg));
|
|
669
1102
|
}
|
|
670
1103
|
function resolveWalletKey(program, cfg) {
|
|
671
|
-
const opts = program
|
|
1104
|
+
const opts = getCommandOptions(program);
|
|
672
1105
|
if (opts.walletKeyFile) {
|
|
673
|
-
return
|
|
1106
|
+
return readFileSync2(opts.walletKeyFile, "utf-8").trim();
|
|
674
1107
|
}
|
|
675
1108
|
if (process.env.ALCHEMY_WALLET_KEY) {
|
|
676
1109
|
return process.env.ALCHEMY_WALLET_KEY;
|
|
677
1110
|
}
|
|
678
1111
|
const config = cfg ?? load();
|
|
679
1112
|
if (config.wallet_key_file) {
|
|
680
|
-
return
|
|
1113
|
+
return readFileSync2(config.wallet_key_file, "utf-8").trim();
|
|
1114
|
+
}
|
|
1115
|
+
return void 0;
|
|
1116
|
+
}
|
|
1117
|
+
function resolveSolanaWalletKey(program, cfg) {
|
|
1118
|
+
const opts = getCommandOptions(program);
|
|
1119
|
+
if (opts.solanaWalletKeyFile) {
|
|
1120
|
+
return readFileSync2(opts.solanaWalletKeyFile, "utf-8").trim();
|
|
1121
|
+
}
|
|
1122
|
+
if (process.env.ALCHEMY_SOLANA_WALLET_KEY) {
|
|
1123
|
+
return process.env.ALCHEMY_SOLANA_WALLET_KEY;
|
|
1124
|
+
}
|
|
1125
|
+
const config = cfg ?? load();
|
|
1126
|
+
if (config.solana_wallet_key_file) {
|
|
1127
|
+
return readFileSync2(config.solana_wallet_key_file, "utf-8").trim();
|
|
1128
|
+
}
|
|
1129
|
+
return void 0;
|
|
1130
|
+
}
|
|
1131
|
+
function resolveGasSponsored(program, cfg) {
|
|
1132
|
+
const opts = getCommandOptions(program);
|
|
1133
|
+
if (opts.gasSponsored) return true;
|
|
1134
|
+
if (process.env.ALCHEMY_EVM_GAS_SPONSORED) {
|
|
1135
|
+
return process.env.ALCHEMY_EVM_GAS_SPONSORED.trim().toLowerCase() === "true";
|
|
1136
|
+
}
|
|
1137
|
+
const config = cfg ?? load();
|
|
1138
|
+
return config.evm_gas_sponsored === true;
|
|
1139
|
+
}
|
|
1140
|
+
function resolveGasPolicyId(program, cfg) {
|
|
1141
|
+
const opts = getCommandOptions(program);
|
|
1142
|
+
if (opts.gasPolicyId) return opts.gasPolicyId;
|
|
1143
|
+
if (process.env.ALCHEMY_EVM_GAS_POLICY_ID) return process.env.ALCHEMY_EVM_GAS_POLICY_ID;
|
|
1144
|
+
const config = cfg ?? load();
|
|
1145
|
+
return config.evm_gas_policy_id;
|
|
1146
|
+
}
|
|
1147
|
+
function resolveSolanaFeeSponsored(program, cfg) {
|
|
1148
|
+
const opts = getCommandOptions(program);
|
|
1149
|
+
if (opts.feeSponsored) return true;
|
|
1150
|
+
if (process.env.ALCHEMY_SOLANA_FEE_SPONSORED) {
|
|
1151
|
+
return process.env.ALCHEMY_SOLANA_FEE_SPONSORED.trim().toLowerCase() === "true";
|
|
681
1152
|
}
|
|
1153
|
+
const config = cfg ?? load();
|
|
1154
|
+
return config.solana_fee_sponsored === true;
|
|
1155
|
+
}
|
|
1156
|
+
function resolveSolanaFeePolicyId(program, cfg) {
|
|
1157
|
+
const opts = getCommandOptions(program);
|
|
1158
|
+
if (opts.feePolicyId) return opts.feePolicyId;
|
|
1159
|
+
if (process.env.ALCHEMY_SOLANA_FEE_POLICY_ID) return process.env.ALCHEMY_SOLANA_FEE_POLICY_ID;
|
|
1160
|
+
const config = cfg ?? load();
|
|
1161
|
+
return config.solana_fee_policy_id;
|
|
1162
|
+
}
|
|
1163
|
+
function parseBoolean(value) {
|
|
1164
|
+
const normalized = value.trim().toLowerCase();
|
|
1165
|
+
if (normalized === "true" || normalized === "1") return true;
|
|
1166
|
+
if (normalized === "false" || normalized === "0") return false;
|
|
682
1167
|
return void 0;
|
|
683
1168
|
}
|
|
1169
|
+
function resolveActiveSigner(program, cfg) {
|
|
1170
|
+
const opts = getCommandOptions(program);
|
|
1171
|
+
if (opts.signer === "session" || opts.signer === "local") {
|
|
1172
|
+
return opts.signer;
|
|
1173
|
+
}
|
|
1174
|
+
const env = process.env.ALCHEMY_ACTIVE_SIGNER;
|
|
1175
|
+
if (env === "session" || env === "local") {
|
|
1176
|
+
return env;
|
|
1177
|
+
}
|
|
1178
|
+
const config = cfg ?? load();
|
|
1179
|
+
if (config.active_signer === "session" || config.active_signer === "local") {
|
|
1180
|
+
return config.active_signer;
|
|
1181
|
+
}
|
|
1182
|
+
if (process.env.ALCHEMY_DELEGATED_WALLET !== void 0) {
|
|
1183
|
+
const parsed = parseBoolean(process.env.ALCHEMY_DELEGATED_WALLET);
|
|
1184
|
+
if (parsed === true) return "session";
|
|
1185
|
+
}
|
|
1186
|
+
return void 0;
|
|
1187
|
+
}
|
|
1188
|
+
function resolveDelegatedMode(program, cfg) {
|
|
1189
|
+
return resolveActiveSigner(program, cfg) === "session";
|
|
1190
|
+
}
|
|
684
1191
|
function clientFromFlags(program, opts) {
|
|
685
1192
|
const cfg = load();
|
|
686
|
-
const network = resolveNetwork(program, cfg, opts?.defaultNetwork);
|
|
1193
|
+
const network = opts?.forceNetwork ?? resolveNetwork(program, cfg, opts?.defaultNetwork);
|
|
687
1194
|
debug(`using network=${network}`);
|
|
688
|
-
const programOpts = program.opts();
|
|
689
|
-
if (programOpts.accessKey) {
|
|
690
|
-
throw errInvalidArgs(
|
|
691
|
-
"--access-key is for admin commands (apps, chains, webhooks). Use --api-key for RPC commands."
|
|
692
|
-
);
|
|
693
|
-
}
|
|
694
1195
|
if (resolveX402(program, cfg)) {
|
|
695
1196
|
const walletKey = resolveWalletKey(program, cfg);
|
|
696
1197
|
if (!walletKey) throw errWalletKeyRequired();
|
|
@@ -715,23 +1216,51 @@ function appNetworkToSlug(rpcUrl) {
|
|
|
715
1216
|
async function resolveConfiguredNetworkSlugs(program, appIdOverride) {
|
|
716
1217
|
const appId = appIdOverride || resolveAppId(program);
|
|
717
1218
|
if (!appId) throw errAppRequired();
|
|
718
|
-
const admin =
|
|
1219
|
+
const admin = adminClientFromFlags(program);
|
|
719
1220
|
const app = await admin.getApp(appId);
|
|
720
1221
|
const slugs = app.chainNetworks.map((network) => appNetworkToSlug(network.rpcUrl)).filter((slug) => Boolean(slug));
|
|
721
1222
|
return Array.from(new Set(slugs)).sort((a, b) => a.localeCompare(b));
|
|
722
1223
|
}
|
|
1224
|
+
function resolveWalletSession() {
|
|
1225
|
+
const session = loadSession();
|
|
1226
|
+
if (!session) return null;
|
|
1227
|
+
if (!isSessionValid(session)) return null;
|
|
1228
|
+
return session;
|
|
1229
|
+
}
|
|
1230
|
+
var resolveDelegatedSession = resolveWalletSession;
|
|
723
1231
|
|
|
724
1232
|
export {
|
|
725
1233
|
AdminClient,
|
|
1234
|
+
getRPCNetworks,
|
|
1235
|
+
getRPCNetworkIds,
|
|
1236
|
+
isSolanaNetwork,
|
|
1237
|
+
nativeTokenSymbol,
|
|
1238
|
+
createPendingSession,
|
|
1239
|
+
loadSession,
|
|
1240
|
+
loadStoredSession,
|
|
1241
|
+
saveSession,
|
|
1242
|
+
updateSession,
|
|
1243
|
+
clearSession,
|
|
1244
|
+
isSessionValid,
|
|
726
1245
|
resolveAPIKey,
|
|
727
1246
|
resolveAccessKey,
|
|
728
1247
|
resolveNetwork,
|
|
1248
|
+
resolveSolanaNetwork,
|
|
729
1249
|
resolveAppId,
|
|
730
1250
|
resolveAuthToken,
|
|
731
1251
|
adminClientFromFlags,
|
|
732
1252
|
resolveX402,
|
|
733
1253
|
resolveX402Client,
|
|
734
1254
|
resolveWalletKey,
|
|
1255
|
+
resolveSolanaWalletKey,
|
|
1256
|
+
resolveGasSponsored,
|
|
1257
|
+
resolveGasPolicyId,
|
|
1258
|
+
resolveSolanaFeeSponsored,
|
|
1259
|
+
resolveSolanaFeePolicyId,
|
|
1260
|
+
resolveActiveSigner,
|
|
1261
|
+
resolveDelegatedMode,
|
|
735
1262
|
clientFromFlags,
|
|
736
|
-
resolveConfiguredNetworkSlugs
|
|
1263
|
+
resolveConfiguredNetworkSlugs,
|
|
1264
|
+
resolveWalletSession,
|
|
1265
|
+
resolveDelegatedSession
|
|
737
1266
|
};
|