@xona-labs/xpay 0.1.0
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/LICENSE +21 -0
- package/README.md +226 -0
- package/dist/cli/accounts.d.ts +13 -0
- package/dist/cli/accounts.d.ts.map +1 -0
- package/dist/cli/accounts.js +66 -0
- package/dist/cli/accounts.js.map +1 -0
- package/dist/cli/balance.d.ts +14 -0
- package/dist/cli/balance.d.ts.map +1 -0
- package/dist/cli/balance.js +60 -0
- package/dist/cli/balance.js.map +1 -0
- package/dist/cli/common.d.ts +20 -0
- package/dist/cli/common.d.ts.map +1 -0
- package/dist/cli/common.js +58 -0
- package/dist/cli/common.js.map +1 -0
- package/dist/cli/discover.d.ts +12 -0
- package/dist/cli/discover.d.ts.map +1 -0
- package/dist/cli/discover.js +69 -0
- package/dist/cli/discover.js.map +1 -0
- package/dist/cli/guardrail.d.ts +16 -0
- package/dist/cli/guardrail.d.ts.map +1 -0
- package/dist/cli/guardrail.js +71 -0
- package/dist/cli/guardrail.js.map +1 -0
- package/dist/cli/history.d.ts +16 -0
- package/dist/cli/history.d.ts.map +1 -0
- package/dist/cli/history.js +59 -0
- package/dist/cli/history.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +165 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +23 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +114 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/mcp-server.d.ts +26 -0
- package/dist/cli/mcp-server.d.ts.map +1 -0
- package/dist/cli/mcp-server.js +112 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/pay.d.ts +15 -0
- package/dist/cli/pay.d.ts.map +1 -0
- package/dist/cli/pay.js +76 -0
- package/dist/cli/pay.js.map +1 -0
- package/dist/cli/transfer.d.ts +19 -0
- package/dist/cli/transfer.d.ts.map +1 -0
- package/dist/cli/transfer.js +66 -0
- package/dist/cli/transfer.js.map +1 -0
- package/dist/discover/cache.d.ts +24 -0
- package/dist/discover/cache.d.ts.map +1 -0
- package/dist/discover/cache.js +94 -0
- package/dist/discover/cache.js.map +1 -0
- package/dist/discover/index.d.ts +21 -0
- package/dist/discover/index.d.ts.map +1 -0
- package/dist/discover/index.js +88 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/discover/payai.d.ts +18 -0
- package/dist/discover/payai.d.ts.map +1 -0
- package/dist/discover/payai.js +56 -0
- package/dist/discover/payai.js.map +1 -0
- package/dist/do/index.d.ts +17 -0
- package/dist/do/index.d.ts.map +1 -0
- package/dist/do/index.js +32 -0
- package/dist/do/index.js.map +1 -0
- package/dist/guardrail/index.d.ts +47 -0
- package/dist/guardrail/index.d.ts.map +1 -0
- package/dist/guardrail/index.js +99 -0
- package/dist/guardrail/index.js.map +1 -0
- package/dist/history/evm.d.ts +21 -0
- package/dist/history/evm.d.ts.map +1 -0
- package/dist/history/evm.js +118 -0
- package/dist/history/evm.js.map +1 -0
- package/dist/history/index.d.ts +19 -0
- package/dist/history/index.d.ts.map +1 -0
- package/dist/history/index.js +45 -0
- package/dist/history/index.js.map +1 -0
- package/dist/history/solana.d.ts +20 -0
- package/dist/history/solana.d.ts.map +1 -0
- package/dist/history/solana.js +97 -0
- package/dist/history/solana.js.map +1 -0
- package/dist/history/types.d.ts +26 -0
- package/dist/history/types.d.ts.map +1 -0
- package/dist/history/types.js +10 -0
- package/dist/history/types.js.map +1 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/profile/derive.d.ts +28 -0
- package/dist/profile/derive.d.ts.map +1 -0
- package/dist/profile/derive.js +75 -0
- package/dist/profile/derive.js.map +1 -0
- package/dist/profile/index.d.ts +74 -0
- package/dist/profile/index.d.ts.map +1 -0
- package/dist/profile/index.js +115 -0
- package/dist/profile/index.js.map +1 -0
- package/dist/profile/storage.d.ts +35 -0
- package/dist/profile/storage.d.ts.map +1 -0
- package/dist/profile/storage.js +162 -0
- package/dist/profile/storage.js.map +1 -0
- package/dist/profile/types.d.ts +69 -0
- package/dist/profile/types.d.ts.map +1 -0
- package/dist/profile/types.js +9 -0
- package/dist/profile/types.js.map +1 -0
- package/dist/signers/index.d.ts +5 -0
- package/dist/signers/index.d.ts.map +1 -0
- package/dist/signers/index.js +5 -0
- package/dist/signers/index.js.map +1 -0
- package/dist/signers/phantom.d.ts +14 -0
- package/dist/signers/phantom.d.ts.map +1 -0
- package/dist/signers/phantom.js +12 -0
- package/dist/signers/phantom.js.map +1 -0
- package/dist/signers/privy.d.ts +20 -0
- package/dist/signers/privy.d.ts.map +1 -0
- package/dist/signers/privy.js +15 -0
- package/dist/signers/privy.js.map +1 -0
- package/dist/signers/raw-evm.d.ts +15 -0
- package/dist/signers/raw-evm.d.ts.map +1 -0
- package/dist/signers/raw-evm.js +70 -0
- package/dist/signers/raw-evm.js.map +1 -0
- package/dist/signers/raw-solana.d.ts +15 -0
- package/dist/signers/raw-solana.d.ts.map +1 -0
- package/dist/signers/raw-solana.js +88 -0
- package/dist/signers/raw-solana.js.map +1 -0
- package/dist/tools/index.d.ts +48 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +164 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/transfer/index.d.ts +30 -0
- package/dist/transfer/index.d.ts.map +1 -0
- package/dist/transfer/index.js +86 -0
- package/dist/transfer/index.js.map +1 -0
- package/dist/types.d.ts +203 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +56 -0
- package/dist/types.js.map +1 -0
- package/dist/use/index.d.ts +38 -0
- package/dist/use/index.d.ts.map +1 -0
- package/dist/use/index.js +173 -0
- package/dist/use/index.js.map +1 -0
- package/dist/wallet/index.d.ts +31 -0
- package/dist/wallet/index.d.ts.map +1 -0
- package/dist/wallet/index.js +56 -0
- package/dist/wallet/index.js.map +1 -0
- package/package.json +70 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @xona-labs/xpay — discovery + usage layer for agentic commerce.
|
|
3
|
+
*
|
|
4
|
+
* Quick start:
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { createXPay, rawSolanaSigner } from "@xona-labs/xpay";
|
|
7
|
+
*
|
|
8
|
+
* const xpay = createXPay({
|
|
9
|
+
* networks: ["solana", "base"],
|
|
10
|
+
* signers: { solana: rawSolanaSigner(SECRET_KEY) },
|
|
11
|
+
* });
|
|
12
|
+
*
|
|
13
|
+
* const results = await xpay.discover({ query: "weather forecast" });
|
|
14
|
+
* const result = await xpay.use(results[0]);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { type Wallet } from "./wallet/index.js";
|
|
18
|
+
import { Guardrail, type GuardrailConfig } from "./guardrail/index.js";
|
|
19
|
+
import { type LoadedProfile } from "./profile/index.js";
|
|
20
|
+
import { type HistoryEntry, type HistoryOptions } from "./history/index.js";
|
|
21
|
+
import { type TransferResult } from "./transfer/index.js";
|
|
22
|
+
import type { DiscoverOptions, Resource, UseResult, Network, Signer } from "./types.js";
|
|
23
|
+
export * from "./types.js";
|
|
24
|
+
export * from "./signers/index.js";
|
|
25
|
+
export * from "./tools/index.js";
|
|
26
|
+
export * from "./profile/index.js";
|
|
27
|
+
export * from "./history/index.js";
|
|
28
|
+
export * from "./transfer/index.js";
|
|
29
|
+
export { Guardrail } from "./guardrail/index.js";
|
|
30
|
+
/**
|
|
31
|
+
* Direct access to the discovery layer for callers (e.g. server routes) that
|
|
32
|
+
* want catalog data without configuring signers.
|
|
33
|
+
*/
|
|
34
|
+
export { discover } from "./discover/index.js";
|
|
35
|
+
export { fetchPayAIResources } from "./discover/payai.js";
|
|
36
|
+
/** Options for {@link createXPay}. */
|
|
37
|
+
export interface XPayOptions {
|
|
38
|
+
/**
|
|
39
|
+
* A loaded profile — derives `networks`, `signers`, and `guardrail` from
|
|
40
|
+
* the profile's keyfile and config. Mutually exclusive with the manual
|
|
41
|
+
* `networks` + `signers` shape below.
|
|
42
|
+
*/
|
|
43
|
+
profile?: LoadedProfile;
|
|
44
|
+
/** Networks the wallet will track. First entry is the default for payments. */
|
|
45
|
+
networks?: Network[];
|
|
46
|
+
/** Signers keyed by network. At minimum, one signer must be provided. */
|
|
47
|
+
signers?: Partial<Record<Network, Signer>>;
|
|
48
|
+
/** Optional spending guardrail enforced before every {@link XPay.use} call. */
|
|
49
|
+
guardrail?: GuardrailConfig;
|
|
50
|
+
/** Override built-in catalog endpoints (for self-hosted facilitators / tests). */
|
|
51
|
+
catalogs?: Partial<Record<string, string>>;
|
|
52
|
+
}
|
|
53
|
+
/** The xPay client returned by {@link createXPay}. */
|
|
54
|
+
export interface XPay {
|
|
55
|
+
wallet: Wallet;
|
|
56
|
+
guardrail: Guardrail;
|
|
57
|
+
/** Find paid services across configured catalogs. */
|
|
58
|
+
discover(opts?: DiscoverOptions): Promise<Resource[]>;
|
|
59
|
+
/** Call a specific resource — handles payment + retry. */
|
|
60
|
+
use(resource: Resource, opts?: {
|
|
61
|
+
body?: unknown;
|
|
62
|
+
headers?: Record<string, string>;
|
|
63
|
+
}): Promise<UseResult>;
|
|
64
|
+
/**
|
|
65
|
+
* Call any URL that supports x402 — even one not in the catalog. Probes the
|
|
66
|
+
* URL, follows the 402 challenge, settles, retries.
|
|
67
|
+
*/
|
|
68
|
+
useByUrl(url: string, opts?: {
|
|
69
|
+
method?: string;
|
|
70
|
+
body?: unknown;
|
|
71
|
+
headers?: Record<string, string>;
|
|
72
|
+
}): Promise<UseResult>;
|
|
73
|
+
/** Search by intent, pick the top result, and call it. The thesis in one method. */
|
|
74
|
+
do(query: string, opts?: {
|
|
75
|
+
body?: unknown;
|
|
76
|
+
}): Promise<UseResult>;
|
|
77
|
+
/** Recent USDC activity across all configured networks (merged + sorted). */
|
|
78
|
+
history(opts?: HistoryOptions): Promise<HistoryEntry[]>;
|
|
79
|
+
/** Direct USDC transfer (no x402). Subject to the same guardrail. */
|
|
80
|
+
transfer(args: {
|
|
81
|
+
amount: number;
|
|
82
|
+
to: string;
|
|
83
|
+
network?: Network;
|
|
84
|
+
token?: "USDC";
|
|
85
|
+
}): Promise<TransferResult>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create an xPay client.
|
|
89
|
+
*
|
|
90
|
+
* This is the single entry point for builders. Everything else is exposed for
|
|
91
|
+
* advanced cases (custom signers, manual discovery, raw x402 calls).
|
|
92
|
+
*/
|
|
93
|
+
export declare function createXPay(options: XPayOptions): XPay;
|
|
94
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @xona-labs/xpay — discovery + usage layer for agentic commerce.
|
|
3
|
+
*
|
|
4
|
+
* Quick start:
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { createXPay, rawSolanaSigner } from "@xona-labs/xpay";
|
|
7
|
+
*
|
|
8
|
+
* const xpay = createXPay({
|
|
9
|
+
* networks: ["solana", "base"],
|
|
10
|
+
* signers: { solana: rawSolanaSigner(SECRET_KEY) },
|
|
11
|
+
* });
|
|
12
|
+
*
|
|
13
|
+
* const results = await xpay.discover({ query: "weather forecast" });
|
|
14
|
+
* const result = await xpay.use(results[0]);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { createWallet } from "./wallet/index.js";
|
|
18
|
+
import { discover } from "./discover/index.js";
|
|
19
|
+
import { use, useByUrl } from "./use/index.js";
|
|
20
|
+
import { doIt } from "./do/index.js";
|
|
21
|
+
import { Guardrail } from "./guardrail/index.js";
|
|
22
|
+
import { signersFromProfile } from "./profile/index.js";
|
|
23
|
+
import { getHistory } from "./history/index.js";
|
|
24
|
+
import { transfer } from "./transfer/index.js";
|
|
25
|
+
export * from "./types.js";
|
|
26
|
+
export * from "./signers/index.js";
|
|
27
|
+
export * from "./tools/index.js";
|
|
28
|
+
export * from "./profile/index.js";
|
|
29
|
+
export * from "./history/index.js";
|
|
30
|
+
export * from "./transfer/index.js";
|
|
31
|
+
export { Guardrail } from "./guardrail/index.js";
|
|
32
|
+
/**
|
|
33
|
+
* Direct access to the discovery layer for callers (e.g. server routes) that
|
|
34
|
+
* want catalog data without configuring signers.
|
|
35
|
+
*/
|
|
36
|
+
export { discover } from "./discover/index.js";
|
|
37
|
+
export { fetchPayAIResources } from "./discover/payai.js";
|
|
38
|
+
/**
|
|
39
|
+
* Create an xPay client.
|
|
40
|
+
*
|
|
41
|
+
* This is the single entry point for builders. Everything else is exposed for
|
|
42
|
+
* advanced cases (custom signers, manual discovery, raw x402 calls).
|
|
43
|
+
*/
|
|
44
|
+
export function createXPay(options) {
|
|
45
|
+
// Resolve networks + signers from either the manual config or a profile.
|
|
46
|
+
let networks = options.networks;
|
|
47
|
+
let signers = options.signers;
|
|
48
|
+
let guardrailConfig = options.guardrail;
|
|
49
|
+
if (options.profile) {
|
|
50
|
+
networks ??= options.profile.config.networks;
|
|
51
|
+
signers ??= signersFromProfile(options.profile);
|
|
52
|
+
guardrailConfig ??= options.profile.config.guardrail;
|
|
53
|
+
}
|
|
54
|
+
if (!networks?.length) {
|
|
55
|
+
throw new Error("createXPay: at least one network must be configured (via `networks` or `profile`)");
|
|
56
|
+
}
|
|
57
|
+
if (!signers || Object.keys(signers).length === 0) {
|
|
58
|
+
throw new Error("createXPay: at least one signer must be provided (via `signers` or `profile`)");
|
|
59
|
+
}
|
|
60
|
+
const walletOpts = { networks, signers };
|
|
61
|
+
const wallet = createWallet(walletOpts);
|
|
62
|
+
const guardrail = new Guardrail(guardrailConfig);
|
|
63
|
+
return {
|
|
64
|
+
wallet,
|
|
65
|
+
guardrail,
|
|
66
|
+
discover: (opts) => discover({ ...opts, catalogs: options.catalogs }),
|
|
67
|
+
use: (resource, opts) => use({ resource, wallet, guardrail, ...opts }),
|
|
68
|
+
useByUrl: (url, opts) => useByUrl({ url, wallet, guardrail, ...opts }),
|
|
69
|
+
do: (query, opts) => doIt({ query, wallet, guardrail, ...opts }),
|
|
70
|
+
history: (opts) => getHistory(wallet, opts),
|
|
71
|
+
transfer: (args) => transfer({ ...args, wallet, guardrail }),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive Solana + EVM keys from a single BIP-39 mnemonic.
|
|
3
|
+
*
|
|
4
|
+
* Paths follow standard wallets so users can recover in Phantom/Solflare
|
|
5
|
+
* (Solana) and MetaMask/Rabby (EVM) using the same seed:
|
|
6
|
+
* - Solana: m/44'/501'/0'/0' (Phantom default)
|
|
7
|
+
* - EVM: m/44'/60'/0'/0/0 (MetaMask default)
|
|
8
|
+
*/
|
|
9
|
+
import { Keypair } from "@solana/web3.js";
|
|
10
|
+
import type { ProfileAddresses } from "./types.js";
|
|
11
|
+
/** Generate a fresh 24-word mnemonic (256-bit entropy). */
|
|
12
|
+
export declare function generateNewMnemonic(): string;
|
|
13
|
+
/** Throws if `mnemonic` is not a valid BIP-39 phrase. */
|
|
14
|
+
export declare function assertValidMnemonic(mnemonic: string): void;
|
|
15
|
+
export interface DerivedKeys {
|
|
16
|
+
solana: {
|
|
17
|
+
keypair: Keypair;
|
|
18
|
+
secretKeyBase58: string;
|
|
19
|
+
address: string;
|
|
20
|
+
};
|
|
21
|
+
evm: {
|
|
22
|
+
privateKey: string;
|
|
23
|
+
address: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export declare function deriveKeysFromMnemonic(mnemonic: string): DerivedKeys;
|
|
27
|
+
export declare function addressesFromMnemonic(mnemonic: string): ProfileAddresses;
|
|
28
|
+
//# sourceMappingURL=derive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/profile/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKnD,2DAA2D;AAC3D,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI1D;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QACN,OAAO,EAAE,OAAO,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,GAAG,EAAE;QACH,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAsBpE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAGxE"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive Solana + EVM keys from a single BIP-39 mnemonic.
|
|
3
|
+
*
|
|
4
|
+
* Paths follow standard wallets so users can recover in Phantom/Solflare
|
|
5
|
+
* (Solana) and MetaMask/Rabby (EVM) using the same seed:
|
|
6
|
+
* - Solana: m/44'/501'/0'/0' (Phantom default)
|
|
7
|
+
* - EVM: m/44'/60'/0'/0/0 (MetaMask default)
|
|
8
|
+
*/
|
|
9
|
+
import { mnemonicToSeedSync, generateMnemonic, validateMnemonic } from "bip39";
|
|
10
|
+
import { derivePath } from "ed25519-hd-key";
|
|
11
|
+
import { Keypair } from "@solana/web3.js";
|
|
12
|
+
import { HDNodeWallet, Mnemonic } from "ethers";
|
|
13
|
+
const SOLANA_PATH = "m/44'/501'/0'/0'";
|
|
14
|
+
const EVM_PATH = "m/44'/60'/0'/0/0";
|
|
15
|
+
/** Generate a fresh 24-word mnemonic (256-bit entropy). */
|
|
16
|
+
export function generateNewMnemonic() {
|
|
17
|
+
return generateMnemonic(256);
|
|
18
|
+
}
|
|
19
|
+
/** Throws if `mnemonic` is not a valid BIP-39 phrase. */
|
|
20
|
+
export function assertValidMnemonic(mnemonic) {
|
|
21
|
+
if (!validateMnemonic(mnemonic)) {
|
|
22
|
+
throw new Error("Invalid BIP-39 mnemonic phrase");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function deriveKeysFromMnemonic(mnemonic) {
|
|
26
|
+
assertValidMnemonic(mnemonic);
|
|
27
|
+
const seed = mnemonicToSeedSync(mnemonic);
|
|
28
|
+
// --- Solana ---
|
|
29
|
+
const solSeed = derivePath(SOLANA_PATH, seed.toString("hex")).key;
|
|
30
|
+
const solKeypair = Keypair.fromSeed(new Uint8Array(solSeed));
|
|
31
|
+
// --- EVM ---
|
|
32
|
+
const evmWallet = HDNodeWallet.fromMnemonic(Mnemonic.fromPhrase(mnemonic), EVM_PATH);
|
|
33
|
+
return {
|
|
34
|
+
solana: {
|
|
35
|
+
keypair: solKeypair,
|
|
36
|
+
secretKeyBase58: base58Encode(solKeypair.secretKey),
|
|
37
|
+
address: solKeypair.publicKey.toBase58(),
|
|
38
|
+
},
|
|
39
|
+
evm: {
|
|
40
|
+
privateKey: evmWallet.privateKey,
|
|
41
|
+
address: evmWallet.address,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function addressesFromMnemonic(mnemonic) {
|
|
46
|
+
const k = deriveKeysFromMnemonic(mnemonic);
|
|
47
|
+
return { solana: k.solana.address, evm: k.evm.address };
|
|
48
|
+
}
|
|
49
|
+
/** Tiny Base58 encoder (avoids adding bs58 just for this). */
|
|
50
|
+
function base58Encode(bytes) {
|
|
51
|
+
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
52
|
+
if (bytes.length === 0)
|
|
53
|
+
return "";
|
|
54
|
+
const digits = [0];
|
|
55
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
56
|
+
let carry = bytes[i];
|
|
57
|
+
for (let j = 0; j < digits.length; j++) {
|
|
58
|
+
carry += digits[j] << 8;
|
|
59
|
+
digits[j] = carry % 58;
|
|
60
|
+
carry = (carry / 58) | 0;
|
|
61
|
+
}
|
|
62
|
+
while (carry > 0) {
|
|
63
|
+
digits.push(carry % 58);
|
|
64
|
+
carry = (carry / 58) | 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Preserve leading zero bytes as leading '1's.
|
|
68
|
+
let out = "";
|
|
69
|
+
for (let i = 0; i < bytes.length && bytes[i] === 0; i++)
|
|
70
|
+
out += "1";
|
|
71
|
+
for (let i = digits.length - 1; i >= 0; i--)
|
|
72
|
+
out += ALPHABET[digits[i]];
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=derive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../../src/profile/derive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile API — public SDK surface for keyfile management.
|
|
3
|
+
*
|
|
4
|
+
* Programmatic usage:
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { initProfile, loadProfile, listProfiles } from "@xona-labs/xpay";
|
|
7
|
+
*
|
|
8
|
+
* const created = await initProfile({ name: "default", passphrase: "..." });
|
|
9
|
+
* console.log(created.mnemonic); // back this up!
|
|
10
|
+
* console.log(created.addresses); // { solana, evm }
|
|
11
|
+
*
|
|
12
|
+
* const p = await loadProfile({ name: "default", passphrase: "..." });
|
|
13
|
+
* // → can be fed directly to createXPay({ profile: p })
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* CLI usage is a thin wrapper around these functions.
|
|
17
|
+
*/
|
|
18
|
+
import type { LoadedProfile, ProfileConfig, WalletFile } from "./types.js";
|
|
19
|
+
import type { Signer } from "../types.js";
|
|
20
|
+
export * from "./types.js";
|
|
21
|
+
export { generateNewMnemonic, addressesFromMnemonic } from "./derive.js";
|
|
22
|
+
export { xpayHome, workspaceXpayDir, listProfiles } from "./storage.js";
|
|
23
|
+
export interface InitProfileOptions {
|
|
24
|
+
/** Profile name, defaults to "default". */
|
|
25
|
+
name?: string;
|
|
26
|
+
/** Use existing mnemonic (import) instead of generating one. */
|
|
27
|
+
mnemonic?: string;
|
|
28
|
+
/** Encrypt at rest. Strongly recommended — omit only for ephemeral dev wallets. */
|
|
29
|
+
passphrase?: string;
|
|
30
|
+
/** Use workspace-local `.xpay/` instead of `~/.xpay/`. */
|
|
31
|
+
workspace?: boolean | string;
|
|
32
|
+
/** Overwrite an existing profile with the same name. Default false. */
|
|
33
|
+
overwrite?: boolean;
|
|
34
|
+
/** Override initial config (defaults to Solana + Base). */
|
|
35
|
+
config?: Partial<ProfileConfig>;
|
|
36
|
+
}
|
|
37
|
+
export interface InitProfileResult {
|
|
38
|
+
name: string;
|
|
39
|
+
path: string;
|
|
40
|
+
addresses: WalletFile["addresses"];
|
|
41
|
+
/** Returned once at creation so the caller can show/save it. Never persisted in plaintext when a passphrase is set. */
|
|
42
|
+
mnemonic: string;
|
|
43
|
+
encrypted: boolean;
|
|
44
|
+
}
|
|
45
|
+
export declare function initProfile(opts?: InitProfileOptions): Promise<InitProfileResult>;
|
|
46
|
+
export interface LoadProfileOptions {
|
|
47
|
+
name?: string;
|
|
48
|
+
passphrase?: string;
|
|
49
|
+
workspace?: boolean | string;
|
|
50
|
+
}
|
|
51
|
+
export declare function loadProfile(opts?: LoadProfileOptions): Promise<LoadedProfile>;
|
|
52
|
+
/**
|
|
53
|
+
* Build runtime signers for every network in the profile's config. Used by
|
|
54
|
+
* createXPay when called with `{ profile }`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function signersFromProfile(profile: LoadedProfile): Partial<Record<string, Signer>>;
|
|
57
|
+
/**
|
|
58
|
+
* Update a profile's guardrail on disk. Merges with any existing guardrail
|
|
59
|
+
* (pass undefined to a field to leave it alone; pass null to clear it).
|
|
60
|
+
*/
|
|
61
|
+
export declare function setProfileGuardrail(name: string, guardrail: NonNullable<ProfileConfig["guardrail"]>, opts?: {
|
|
62
|
+
workspace?: boolean | string;
|
|
63
|
+
}): ProfileConfig;
|
|
64
|
+
/** Drop the guardrail entirely (calls now run unconstrained). */
|
|
65
|
+
export declare function clearProfileGuardrail(name: string, opts?: {
|
|
66
|
+
workspace?: boolean | string;
|
|
67
|
+
}): ProfileConfig;
|
|
68
|
+
/** Read the on-disk config (guardrail, networks, link, etc.) for a profile. */
|
|
69
|
+
export declare function readProfileConfig(name: string, opts?: {
|
|
70
|
+
workspace?: boolean | string;
|
|
71
|
+
}): ProfileConfig;
|
|
72
|
+
export { profilePath, profileExists } from "./storage.js";
|
|
73
|
+
export { deriveKeysFromMnemonic } from "./derive.js";
|
|
74
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/profile/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAeH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMxE,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,uEAAuE;IACvE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACnC,uHAAuH;IACvH,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmB3F;AAMD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC9B;AAED,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC,CAYvF;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkB1F;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,EAClD,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GAC1C,aAAa,CAMf;AAED,iEAAiE;AACjE,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GAC1C,aAAa,CAMf;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GAC1C,aAAa,CAEf;AAMD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile API — public SDK surface for keyfile management.
|
|
3
|
+
*
|
|
4
|
+
* Programmatic usage:
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { initProfile, loadProfile, listProfiles } from "@xona-labs/xpay";
|
|
7
|
+
*
|
|
8
|
+
* const created = await initProfile({ name: "default", passphrase: "..." });
|
|
9
|
+
* console.log(created.mnemonic); // back this up!
|
|
10
|
+
* console.log(created.addresses); // { solana, evm }
|
|
11
|
+
*
|
|
12
|
+
* const p = await loadProfile({ name: "default", passphrase: "..." });
|
|
13
|
+
* // → can be fed directly to createXPay({ profile: p })
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* CLI usage is a thin wrapper around these functions.
|
|
17
|
+
*/
|
|
18
|
+
import { addressesFromMnemonic, generateNewMnemonic, deriveKeysFromMnemonic } from "./derive.js";
|
|
19
|
+
import { buildWalletFile, defaultConfig, profileExists, profilePath, readConfigFile, readWalletFile, unlockWalletFile, writeConfigFile, writeWalletFile, } from "./storage.js";
|
|
20
|
+
import { rawSolanaSigner } from "../signers/raw-solana.js";
|
|
21
|
+
import { rawEvmSigner } from "../signers/raw-evm.js";
|
|
22
|
+
export * from "./types.js";
|
|
23
|
+
export { generateNewMnemonic, addressesFromMnemonic } from "./derive.js";
|
|
24
|
+
export { xpayHome, workspaceXpayDir, listProfiles } from "./storage.js";
|
|
25
|
+
export async function initProfile(opts = {}) {
|
|
26
|
+
const name = opts.name ?? "default";
|
|
27
|
+
if (!opts.overwrite && profileExists(name, { workspace: opts.workspace })) {
|
|
28
|
+
throw new Error(`Profile "${name}" already exists. Pass { overwrite: true } to replace it.`);
|
|
29
|
+
}
|
|
30
|
+
const mnemonic = opts.mnemonic ?? generateNewMnemonic();
|
|
31
|
+
const addresses = addressesFromMnemonic(mnemonic);
|
|
32
|
+
const wallet = buildWalletFile({ mnemonic, addresses, passphrase: opts.passphrase });
|
|
33
|
+
const dir = profilePath(name, { workspace: opts.workspace });
|
|
34
|
+
writeWalletFile(dir, wallet);
|
|
35
|
+
writeConfigFile(dir, { ...defaultConfig(), ...opts.config });
|
|
36
|
+
return {
|
|
37
|
+
name,
|
|
38
|
+
path: dir,
|
|
39
|
+
addresses,
|
|
40
|
+
mnemonic,
|
|
41
|
+
encrypted: Boolean(opts.passphrase),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export async function loadProfile(opts = {}) {
|
|
45
|
+
const name = opts.name ?? "default";
|
|
46
|
+
const dir = profilePath(name, { workspace: opts.workspace });
|
|
47
|
+
const wallet = readWalletFile(dir);
|
|
48
|
+
const mnemonic = unlockWalletFile(wallet, opts.passphrase);
|
|
49
|
+
return {
|
|
50
|
+
name,
|
|
51
|
+
path: dir,
|
|
52
|
+
addresses: wallet.addresses,
|
|
53
|
+
config: readConfigFile(dir),
|
|
54
|
+
mnemonic,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// -----------------------------------------------------------------------------
|
|
58
|
+
// signers from profile
|
|
59
|
+
// -----------------------------------------------------------------------------
|
|
60
|
+
/**
|
|
61
|
+
* Build runtime signers for every network in the profile's config. Used by
|
|
62
|
+
* createXPay when called with `{ profile }`.
|
|
63
|
+
*/
|
|
64
|
+
export function signersFromProfile(profile) {
|
|
65
|
+
const keys = deriveKeysFromMnemonic(profile.mnemonic);
|
|
66
|
+
const out = {};
|
|
67
|
+
for (const network of profile.config.networks) {
|
|
68
|
+
if (network === "solana") {
|
|
69
|
+
out.solana = rawSolanaSigner({
|
|
70
|
+
secretKey: keys.solana.keypair.secretKey,
|
|
71
|
+
rpcUrl: profile.config.rpcs?.solana,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else if (["base", "ethereum", "arbitrum", "optimism"].includes(network)) {
|
|
75
|
+
out[network] = rawEvmSigner({
|
|
76
|
+
privateKey: keys.evm.privateKey,
|
|
77
|
+
network,
|
|
78
|
+
rpcUrl: profile.config.rpcs?.[network],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
// -----------------------------------------------------------------------------
|
|
85
|
+
// Guardrail mutation
|
|
86
|
+
// -----------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Update a profile's guardrail on disk. Merges with any existing guardrail
|
|
89
|
+
* (pass undefined to a field to leave it alone; pass null to clear it).
|
|
90
|
+
*/
|
|
91
|
+
export function setProfileGuardrail(name, guardrail, opts = {}) {
|
|
92
|
+
const dir = profilePath(name, opts);
|
|
93
|
+
const current = readConfigFile(dir);
|
|
94
|
+
current.guardrail = { ...current.guardrail, ...guardrail };
|
|
95
|
+
writeConfigFile(dir, current);
|
|
96
|
+
return current;
|
|
97
|
+
}
|
|
98
|
+
/** Drop the guardrail entirely (calls now run unconstrained). */
|
|
99
|
+
export function clearProfileGuardrail(name, opts = {}) {
|
|
100
|
+
const dir = profilePath(name, opts);
|
|
101
|
+
const current = readConfigFile(dir);
|
|
102
|
+
delete current.guardrail;
|
|
103
|
+
writeConfigFile(dir, current);
|
|
104
|
+
return current;
|
|
105
|
+
}
|
|
106
|
+
/** Read the on-disk config (guardrail, networks, link, etc.) for a profile. */
|
|
107
|
+
export function readProfileConfig(name, opts = {}) {
|
|
108
|
+
return readConfigFile(profilePath(name, opts));
|
|
109
|
+
}
|
|
110
|
+
// -----------------------------------------------------------------------------
|
|
111
|
+
// re-export for convenience
|
|
112
|
+
// -----------------------------------------------------------------------------
|
|
113
|
+
export { profilePath, profileExists } from "./storage.js";
|
|
114
|
+
export { deriveKeysFromMnemonic } from "./derive.js";
|
|
115
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/profile/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EACL,eAAe,EACf,aAAa,EAEb,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA8BxE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B,EAAE;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;IACpC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,aAAa,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,2DAA2D,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,mBAAmB,EAAE,CAAC;IACxD,MAAM,SAAS,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACrF,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC7D,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,aAAa,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7D,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,GAAG;QACT,SAAS;QACT,QAAQ;QACR,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;KACpC,CAAC;AACJ,CAAC;AAYD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B,EAAE;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;IACpC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3D,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,GAAG;QACT,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC;QAC3B,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAsB;IACvD,MAAM,IAAI,GAAG,sBAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,GAAG,GAAoC,EAAE,CAAC;IAChD,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC9C,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YACzB,GAAG,CAAC,MAAM,GAAG,eAAe,CAAC;gBAC3B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS;gBACxC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM;aACpC,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC;gBAC1B,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU;gBAC/B,OAAO;gBACP,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,SAAkD,EAClD,OAAyC,EAAE;IAE3C,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,CAAC,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC;IAC3D,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,qBAAqB,CACnC,IAAY,EACZ,OAAyC,EAAE;IAE3C,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,SAAS,CAAC;IACzB,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,OAAyC,EAAE;IAE3C,OAAO,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile storage — read/write `wallet.json` + `config.json` under
|
|
3
|
+
* `~/.xpay/<name>/` (or a workspace path) with passphrase-based encryption.
|
|
4
|
+
*
|
|
5
|
+
* Encryption uses Node's built-in crypto (no new deps): scrypt → AES-256-GCM
|
|
6
|
+
* over the mnemonic. AES-GCM gives us authenticated encryption so we detect
|
|
7
|
+
* wrong passphrases / tampering instead of returning garbage.
|
|
8
|
+
*/
|
|
9
|
+
import type { ProfileConfig, WalletFile } from "./types.js";
|
|
10
|
+
/** Root directory holding all profiles. Honors $XPAY_HOME. */
|
|
11
|
+
export declare function xpayHome(): string;
|
|
12
|
+
/** Workspace-local profile dir (when `--workspace` is passed). */
|
|
13
|
+
export declare function workspaceXpayDir(cwd?: string): string;
|
|
14
|
+
export declare function profilePath(name: string, opts?: {
|
|
15
|
+
workspace?: boolean | string;
|
|
16
|
+
}): string;
|
|
17
|
+
export declare function profileExists(name: string, opts?: {
|
|
18
|
+
workspace?: boolean | string;
|
|
19
|
+
}): boolean;
|
|
20
|
+
export declare function listProfiles(opts?: {
|
|
21
|
+
workspace?: boolean | string;
|
|
22
|
+
}): string[];
|
|
23
|
+
export declare function writeWalletFile(dir: string, wallet: WalletFile): void;
|
|
24
|
+
export declare function readWalletFile(dir: string): WalletFile;
|
|
25
|
+
export declare function writeConfigFile(dir: string, config: ProfileConfig): void;
|
|
26
|
+
export declare function readConfigFile(dir: string): ProfileConfig;
|
|
27
|
+
export declare function defaultConfig(): ProfileConfig;
|
|
28
|
+
export interface BuildWalletInput {
|
|
29
|
+
mnemonic: string;
|
|
30
|
+
addresses: WalletFile["addresses"];
|
|
31
|
+
passphrase?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function buildWalletFile(input: BuildWalletInput): WalletFile;
|
|
34
|
+
export declare function unlockWalletFile(wallet: WalletFile, passphrase?: string): string;
|
|
35
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/profile/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO5D,8DAA8D;AAC9D,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,GAAG,SAAgB,GAAG,MAAM,CAE5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GAAG,MAAM,CAO7F;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GAAG,OAAO,CAEhG;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GAAG,MAAM,EAAE,CAclF;AAqDD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,UAAU,GACjB,IAAI,CAMN;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAMtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAGxE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAIzD;AAED,wBAAgB,aAAa,IAAI,aAAa,CAM7C;AAUD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,UAAU,CAYnE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAKhF"}
|