@alchemy/wallet-apis 5.0.0-beta.27 → 5.0.0-beta.29
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/dist/esm/actions/prepareCalls.d.ts +8 -3
- package/dist/esm/actions/prepareCalls.js +8 -0
- package/dist/esm/actions/prepareCalls.js.map +1 -1
- package/dist/esm/actions/requestAccount.d.ts +4 -3
- package/dist/esm/actions/requestAccount.js.map +1 -1
- package/dist/esm/actions/sendPreparedCalls.d.ts +3 -1
- package/dist/esm/actions/sendPreparedCalls.js.map +1 -1
- package/dist/esm/actions/signPreparedCalls.js +1 -1
- package/dist/esm/actions/signPreparedCalls.js.map +1 -1
- package/dist/esm/actions/signSignatureRequest.d.ts +4 -4
- package/dist/esm/actions/signSignatureRequest.js +1 -1
- package/dist/esm/actions/signSignatureRequest.js.map +1 -1
- package/dist/esm/actions/signTypedData.d.ts +14 -4
- package/dist/esm/actions/signTypedData.js.map +1 -1
- package/dist/esm/actions/solana/getCallsStatus.d.ts +24 -0
- package/dist/esm/actions/solana/getCallsStatus.js +44 -0
- package/dist/esm/actions/solana/getCallsStatus.js.map +1 -0
- package/dist/esm/actions/solana/prepareCalls.d.ts +46 -0
- package/dist/esm/actions/solana/prepareCalls.js +70 -0
- package/dist/esm/actions/solana/prepareCalls.js.map +1 -0
- package/dist/esm/actions/solana/sendCalls.d.ts +34 -0
- package/dist/esm/actions/solana/sendCalls.js +44 -0
- package/dist/esm/actions/solana/sendCalls.js.map +1 -0
- package/dist/esm/actions/solana/sendPreparedCalls.d.ts +24 -0
- package/dist/esm/actions/solana/sendPreparedCalls.js +32 -0
- package/dist/esm/actions/solana/sendPreparedCalls.js.map +1 -0
- package/dist/esm/actions/solana/signPreparedCalls.d.ts +23 -0
- package/dist/esm/actions/solana/signPreparedCalls.js +24 -0
- package/dist/esm/actions/solana/signPreparedCalls.js.map +1 -0
- package/dist/esm/actions/solana/signSignatureRequest.d.ts +10 -0
- package/dist/esm/actions/solana/signSignatureRequest.js +33 -0
- package/dist/esm/actions/solana/signSignatureRequest.js.map +1 -0
- package/dist/esm/actions/solana/waitForCallsStatus.d.ts +24 -0
- package/dist/esm/actions/solana/waitForCallsStatus.js +46 -0
- package/dist/esm/actions/solana/waitForCallsStatus.js.map +1 -0
- package/dist/esm/adapters/SolanaSignerError.d.ts +4 -0
- package/dist/esm/adapters/SolanaSignerError.js +13 -0
- package/dist/esm/adapters/SolanaSignerError.js.map +1 -0
- package/dist/esm/adapters/fromKeypair.d.ts +21 -0
- package/dist/esm/adapters/fromKeypair.js +46 -0
- package/dist/esm/adapters/fromKeypair.js.map +1 -0
- package/dist/esm/adapters/fromKitSigner.d.ts +21 -0
- package/dist/esm/adapters/fromKitSigner.js +61 -0
- package/dist/esm/adapters/fromKitSigner.js.map +1 -0
- package/dist/esm/adapters/fromWalletAdapter.d.ts +26 -0
- package/dist/esm/adapters/fromWalletAdapter.js +45 -0
- package/dist/esm/adapters/fromWalletAdapter.js.map +1 -0
- package/dist/esm/adapters/fromWalletStandard.d.ts +31 -0
- package/dist/esm/adapters/fromWalletStandard.js +53 -0
- package/dist/esm/adapters/fromWalletStandard.js.map +1 -0
- package/dist/esm/adapters/resolveSignerSlot.d.ts +10 -0
- package/dist/esm/adapters/resolveSignerSlot.js +39 -0
- package/dist/esm/adapters/resolveSignerSlot.js.map +1 -0
- package/dist/esm/client.d.ts +29 -14
- package/dist/esm/client.js +63 -19
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/decorators/smartWalletActions.js +2 -2
- package/dist/esm/decorators/smartWalletActions.js.map +1 -1
- package/dist/esm/decorators/solanaSmartWalletActions.d.ts +16 -0
- package/dist/esm/decorators/solanaSmartWalletActions.js +16 -0
- package/dist/esm/decorators/solanaSmartWalletActions.js.map +1 -0
- package/dist/esm/experimental/actions/requestQuoteV0.d.ts +34 -7
- package/dist/esm/experimental/actions/requestQuoteV0.js.map +1 -1
- package/dist/esm/exports/index.d.ts +3 -3
- package/dist/esm/exports/index.js.map +1 -1
- package/dist/esm/exports/solana.d.ts +24 -0
- package/dist/esm/exports/solana.js +15 -0
- package/dist/esm/exports/solana.js.map +1 -0
- package/dist/esm/types.d.ts +28 -4
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/assertions.d.ts +4 -2
- package/dist/esm/utils/assertions.js +6 -0
- package/dist/esm/utils/assertions.js.map +1 -1
- package/dist/esm/utils/capabilities.d.ts +22 -6
- package/dist/esm/utils/capabilities.js +19 -2
- package/dist/esm/utils/capabilities.js.map +1 -1
- package/dist/esm/utils/format.js +1 -1
- package/dist/esm/utils/format.js.map +1 -1
- package/dist/esm/utils/schema.d.ts +14 -14
- package/dist/esm/utils/schema.js +35 -39
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/actions/prepareCalls.d.ts +8 -3
- package/dist/types/actions/prepareCalls.d.ts.map +1 -1
- package/dist/types/actions/requestAccount.d.ts +4 -3
- package/dist/types/actions/requestAccount.d.ts.map +1 -1
- package/dist/types/actions/sendPreparedCalls.d.ts +3 -1
- package/dist/types/actions/sendPreparedCalls.d.ts.map +1 -1
- package/dist/types/actions/signSignatureRequest.d.ts +4 -4
- package/dist/types/actions/signSignatureRequest.d.ts.map +1 -1
- package/dist/types/actions/signTypedData.d.ts +14 -4
- package/dist/types/actions/signTypedData.d.ts.map +1 -1
- package/dist/types/actions/solana/getCallsStatus.d.ts +25 -0
- package/dist/types/actions/solana/getCallsStatus.d.ts.map +1 -0
- package/dist/types/actions/solana/prepareCalls.d.ts +47 -0
- package/dist/types/actions/solana/prepareCalls.d.ts.map +1 -0
- package/dist/types/actions/solana/sendCalls.d.ts +35 -0
- package/dist/types/actions/solana/sendCalls.d.ts.map +1 -0
- package/dist/types/actions/solana/sendPreparedCalls.d.ts +25 -0
- package/dist/types/actions/solana/sendPreparedCalls.d.ts.map +1 -0
- package/dist/types/actions/solana/signPreparedCalls.d.ts +24 -0
- package/dist/types/actions/solana/signPreparedCalls.d.ts.map +1 -0
- package/dist/types/actions/solana/signSignatureRequest.d.ts +11 -0
- package/dist/types/actions/solana/signSignatureRequest.d.ts.map +1 -0
- package/dist/types/actions/solana/waitForCallsStatus.d.ts +25 -0
- package/dist/types/actions/solana/waitForCallsStatus.d.ts.map +1 -0
- package/dist/types/adapters/SolanaSignerError.d.ts +5 -0
- package/dist/types/adapters/SolanaSignerError.d.ts.map +1 -0
- package/dist/types/adapters/fromKeypair.d.ts +22 -0
- package/dist/types/adapters/fromKeypair.d.ts.map +1 -0
- package/dist/types/adapters/fromKitSigner.d.ts +22 -0
- package/dist/types/adapters/fromKitSigner.d.ts.map +1 -0
- package/dist/types/adapters/fromWalletAdapter.d.ts +27 -0
- package/dist/types/adapters/fromWalletAdapter.d.ts.map +1 -0
- package/dist/types/adapters/fromWalletStandard.d.ts +32 -0
- package/dist/types/adapters/fromWalletStandard.d.ts.map +1 -0
- package/dist/types/adapters/resolveSignerSlot.d.ts +11 -0
- package/dist/types/adapters/resolveSignerSlot.d.ts.map +1 -0
- package/dist/types/client.d.ts +29 -14
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/decorators/solanaSmartWalletActions.d.ts +17 -0
- package/dist/types/decorators/solanaSmartWalletActions.d.ts.map +1 -0
- package/dist/types/experimental/actions/requestQuoteV0.d.ts +34 -7
- package/dist/types/experimental/actions/requestQuoteV0.d.ts.map +1 -1
- package/dist/types/exports/index.d.ts +3 -3
- package/dist/types/exports/index.d.ts.map +1 -1
- package/dist/types/exports/solana.d.ts +25 -0
- package/dist/types/exports/solana.d.ts.map +1 -0
- package/dist/types/types.d.ts +28 -4
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/assertions.d.ts +4 -2
- package/dist/types/utils/assertions.d.ts.map +1 -1
- package/dist/types/utils/capabilities.d.ts +22 -6
- package/dist/types/utils/capabilities.d.ts.map +1 -1
- package/dist/types/utils/schema.d.ts +14 -14
- package/dist/types/utils/schema.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +26 -9
- package/src/actions/prepareCalls.ts +21 -3
- package/src/actions/requestAccount.ts +7 -5
- package/src/actions/sendPreparedCalls.ts +4 -1
- package/src/actions/signPreparedCalls.ts +1 -1
- package/src/actions/signSignatureRequest.ts +8 -8
- package/src/actions/signTypedData.ts +15 -12
- package/src/actions/solana/getCallsStatus.ts +79 -0
- package/src/actions/solana/prepareCalls.ts +120 -0
- package/src/actions/solana/sendCalls.ts +66 -0
- package/src/actions/solana/sendPreparedCalls.ts +65 -0
- package/src/actions/solana/signPreparedCalls.ts +50 -0
- package/src/actions/solana/signSignatureRequest.ts +63 -0
- package/src/actions/solana/waitForCallsStatus.ts +84 -0
- package/src/adapters/SolanaSignerError.ts +5 -0
- package/src/adapters/fromKeypair.ts +58 -0
- package/src/adapters/fromKitSigner.ts +82 -0
- package/src/adapters/fromWalletAdapter.ts +58 -0
- package/src/adapters/fromWalletStandard.ts +100 -0
- package/src/adapters/resolveSignerSlot.ts +46 -0
- package/src/client.ts +131 -18
- package/src/decorators/smartWalletActions.ts +2 -2
- package/src/decorators/solanaSmartWalletActions.ts +62 -0
- package/src/experimental/actions/requestQuoteV0.ts +26 -11
- package/src/exports/index.ts +8 -4
- package/src/exports/solana.ts +36 -0
- package/src/types.ts +38 -7
- package/src/utils/assertions.ts +17 -2
- package/src/utils/capabilities.ts +40 -8
- package/src/utils/format.ts +1 -1
- package/src/utils/schema.ts +58 -69
- package/src/version.ts +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { SolanaSignerError } from "./SolanaSignerError.js";
|
|
2
|
+
import type { SolanaSigner } from "../types.js";
|
|
3
|
+
|
|
4
|
+
const SIGN_TRANSACTION = "solana:signTransaction";
|
|
5
|
+
|
|
6
|
+
/** Minimal structural shape of a wallet-standard account. */
|
|
7
|
+
export interface WalletStandardAccount {
|
|
8
|
+
address: string;
|
|
9
|
+
publicKey?: Uint8Array;
|
|
10
|
+
chains?: readonly string[];
|
|
11
|
+
features?: readonly string[];
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Minimal structural shape of a wallet-standard wallet. */
|
|
16
|
+
export interface WalletStandardWallet {
|
|
17
|
+
features: { readonly [name: string]: unknown };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface SolanaSignTransactionFeature {
|
|
21
|
+
readonly signTransaction: (
|
|
22
|
+
...inputs: readonly {
|
|
23
|
+
account: WalletStandardAccount;
|
|
24
|
+
transaction: Uint8Array;
|
|
25
|
+
}[]
|
|
26
|
+
) => Promise<readonly { signedTransaction: Uint8Array }[]>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isSolanaSignTransactionFeature(
|
|
30
|
+
feature: unknown,
|
|
31
|
+
): feature is SolanaSignTransactionFeature {
|
|
32
|
+
return (
|
|
33
|
+
typeof feature === "object" &&
|
|
34
|
+
feature !== null &&
|
|
35
|
+
"signTransaction" in feature &&
|
|
36
|
+
typeof (feature as { signTransaction?: unknown }).signTransaction ===
|
|
37
|
+
"function"
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Adapts a Wallet Standard wallet into a {@link SolanaSigner}.
|
|
43
|
+
*
|
|
44
|
+
* Works with any wallet that implements the `solana:signTransaction` feature
|
|
45
|
+
* from the Wallet Standard spec (Phantom, Solflare, etc.). No peer dependency
|
|
46
|
+
* required — the interface uses `Uint8Array` directly.
|
|
47
|
+
*
|
|
48
|
+
* For `@solana/wallet-adapter-react` wallets, use {@link fromWalletAdapter}.
|
|
49
|
+
* For `@solana/kit` signers, use {@link fromKitSigner}. For raw Ed25519
|
|
50
|
+
* keypairs, use {@link fromKeypair}.
|
|
51
|
+
*
|
|
52
|
+
* @param {WalletStandardWallet} wallet - The wallet-standard wallet object
|
|
53
|
+
* @param {WalletStandardAccount} account - The account to sign with
|
|
54
|
+
* @returns {SolanaSigner} A SolanaSigner compatible with `createSmartWalletClient`
|
|
55
|
+
*/
|
|
56
|
+
export function fromWalletStandard(
|
|
57
|
+
wallet: WalletStandardWallet,
|
|
58
|
+
account: WalletStandardAccount,
|
|
59
|
+
): SolanaSigner {
|
|
60
|
+
const feature = wallet.features[SIGN_TRANSACTION];
|
|
61
|
+
|
|
62
|
+
if (!isSolanaSignTransactionFeature(feature)) {
|
|
63
|
+
throw new SolanaSignerError(
|
|
64
|
+
`Wallet does not support the "${SIGN_TRANSACTION}" feature.`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (account.features && !account.features.includes(SIGN_TRANSACTION)) {
|
|
69
|
+
throw new SolanaSignerError(
|
|
70
|
+
`Account ${account.address} does not support the "${SIGN_TRANSACTION}" feature.`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
address: account.address,
|
|
76
|
+
async signTransaction({ transaction }) {
|
|
77
|
+
let output: { signedTransaction: Uint8Array } | undefined;
|
|
78
|
+
try {
|
|
79
|
+
[output] = await feature.signTransaction({ account, transaction });
|
|
80
|
+
} catch (e) {
|
|
81
|
+
throw new SolanaSignerError(
|
|
82
|
+
"Wallet standard wallet failed to sign transaction",
|
|
83
|
+
{ cause: e as Error },
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!output) {
|
|
88
|
+
throw new SolanaSignerError("Wallet returned no signed transaction.");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!(output.signedTransaction instanceof Uint8Array)) {
|
|
92
|
+
throw new SolanaSignerError(
|
|
93
|
+
"Wallet returned an invalid signed transaction.",
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return output;
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SolanaSignerError } from "./SolanaSignerError.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Finds the signature slot index for `signerAddress` by decoding the
|
|
5
|
+
* transaction message and looking up the address in the account keys.
|
|
6
|
+
* Tries `@solana/kit` first, falls back to `@solana/web3.js`.
|
|
7
|
+
*
|
|
8
|
+
* @param {Uint8Array} transaction - The serialized Solana transaction bytes
|
|
9
|
+
* @param {string} signerAddress - The base58-encoded address of the signer
|
|
10
|
+
* @returns {Promise<number>} The slot index, or -1 if the address is not a required signer
|
|
11
|
+
*/
|
|
12
|
+
export async function findSignerSlot(
|
|
13
|
+
transaction: Uint8Array,
|
|
14
|
+
signerAddress: string,
|
|
15
|
+
): Promise<number> {
|
|
16
|
+
let accounts: readonly string[];
|
|
17
|
+
let numRequiredSigners: number;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const { getCompiledTransactionMessageDecoder } = await import(
|
|
21
|
+
"@solana/kit"
|
|
22
|
+
);
|
|
23
|
+
const numSigs = transaction[0];
|
|
24
|
+
const messageBytes = transaction.slice(1 + numSigs * 64);
|
|
25
|
+
const decoded = getCompiledTransactionMessageDecoder().decode(messageBytes);
|
|
26
|
+
accounts = decoded.staticAccounts as readonly string[];
|
|
27
|
+
numRequiredSigners = decoded.header.numSignerAccounts;
|
|
28
|
+
} catch {
|
|
29
|
+
try {
|
|
30
|
+
const { VersionedTransaction } = await import("@solana/web3.js");
|
|
31
|
+
const vtx = VersionedTransaction.deserialize(transaction);
|
|
32
|
+
accounts = vtx.message.staticAccountKeys.map((k) => k.toBase58());
|
|
33
|
+
numRequiredSigners = vtx.message.header.numRequiredSignatures;
|
|
34
|
+
} catch {
|
|
35
|
+
throw new SolanaSignerError(
|
|
36
|
+
"Failed to decode transaction: install @solana/kit or @solana/web3.js",
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const slotIndex = accounts.indexOf(signerAddress);
|
|
42
|
+
if (slotIndex < 0 || slotIndex >= numRequiredSigners) {
|
|
43
|
+
return -1;
|
|
44
|
+
}
|
|
45
|
+
return slotIndex;
|
|
46
|
+
}
|
package/src/client.ts
CHANGED
|
@@ -1,11 +1,51 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseError } from "@alchemy/common";
|
|
2
|
+
import { createClient, defineChain, type Address, type Chain } from "viem";
|
|
2
3
|
import { smartWalletActions } from "./decorators/smartWalletActions.js";
|
|
3
|
-
import
|
|
4
|
+
import { solanaSmartWalletActions } from "./decorators/solanaSmartWalletActions.js";
|
|
5
|
+
import type {
|
|
6
|
+
SmartWalletClient,
|
|
7
|
+
SmartWalletSigner,
|
|
8
|
+
SolanaSmartWalletClient,
|
|
9
|
+
SolanaSigner,
|
|
10
|
+
SolanaChainDef,
|
|
11
|
+
} from "./types.js";
|
|
4
12
|
import { createInternalState } from "./internal.js";
|
|
5
13
|
import { isLocalAccount } from "./utils/assertions.js";
|
|
6
14
|
import type { AlchemyWalletTransport } from "./transport.js";
|
|
15
|
+
import type { SolanaChainId } from "@alchemy/wallet-api-types";
|
|
7
16
|
|
|
8
|
-
|
|
17
|
+
// ── Solana chain definitions ────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
const solanaMainnet: SolanaChainDef = {
|
|
20
|
+
...defineChain({
|
|
21
|
+
id: 0,
|
|
22
|
+
name: "Solana Mainnet",
|
|
23
|
+
nativeCurrency: { name: "SOL", symbol: "SOL", decimals: 9 },
|
|
24
|
+
rpcUrls: { default: { http: [] } },
|
|
25
|
+
}),
|
|
26
|
+
solanaChainId: "solana:mainnet",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const solanaDevnet: SolanaChainDef = {
|
|
30
|
+
...defineChain({
|
|
31
|
+
id: 0,
|
|
32
|
+
name: "Solana Devnet",
|
|
33
|
+
nativeCurrency: { name: "SOL", symbol: "SOL", decimals: 9 },
|
|
34
|
+
rpcUrls: { default: { http: [] } },
|
|
35
|
+
}),
|
|
36
|
+
solanaChainId: "solana:devnet",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const SOLANA_CHAINS: Record<SolanaChainId, SolanaChainDef> = {
|
|
40
|
+
"solana:mainnet": solanaMainnet,
|
|
41
|
+
"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": solanaMainnet,
|
|
42
|
+
"solana:devnet": solanaDevnet,
|
|
43
|
+
"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1": solanaDevnet,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// ── Param types ─────────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
export type CreateEvmSmartWalletClientParams = {
|
|
9
49
|
signer: SmartWalletSigner;
|
|
10
50
|
transport: AlchemyWalletTransport;
|
|
11
51
|
chain: Chain;
|
|
@@ -16,30 +56,71 @@ export type CreateSmartWalletClientParams = {
|
|
|
16
56
|
};
|
|
17
57
|
};
|
|
18
58
|
|
|
59
|
+
export type CreateSolanaSmartWalletClientParams = {
|
|
60
|
+
signer: SolanaSigner;
|
|
61
|
+
transport: AlchemyWalletTransport;
|
|
62
|
+
chain: SolanaChainId;
|
|
63
|
+
account?: string;
|
|
64
|
+
paymaster?: {
|
|
65
|
+
policyId: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Either {@link CreateEvmSmartWalletClientParams} or {@link CreateSolanaSmartWalletClientParams}. */
|
|
70
|
+
export type CreateSmartWalletClientParams =
|
|
71
|
+
| CreateEvmSmartWalletClientParams
|
|
72
|
+
| CreateSolanaSmartWalletClientParams;
|
|
73
|
+
|
|
74
|
+
// ── Factory ─────────────────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
function isSolanaParams(
|
|
77
|
+
params: CreateSmartWalletClientParams,
|
|
78
|
+
): params is CreateSolanaSmartWalletClientParams {
|
|
79
|
+
return typeof params.chain === "string" && params.chain.startsWith("solana:");
|
|
80
|
+
}
|
|
81
|
+
|
|
19
82
|
/**
|
|
20
|
-
* Creates a smart wallet client with
|
|
83
|
+
* Creates a smart wallet client for EVM chains with actions for preparing,
|
|
84
|
+
* signing, and sending user operations.
|
|
21
85
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
|
|
86
|
+
* @param {CreateEvmSmartWalletClientParams} params - EVM client configuration
|
|
87
|
+
* @returns {SmartWalletClient} An EVM smart wallet client with smart wallet actions
|
|
88
|
+
*/
|
|
89
|
+
export function createSmartWalletClient(
|
|
90
|
+
params: CreateEvmSmartWalletClientParams,
|
|
91
|
+
): SmartWalletClient;
|
|
92
|
+
/**
|
|
93
|
+
* Creates a smart wallet client for Solana chains with actions for preparing,
|
|
94
|
+
* signing, and sending transactions.
|
|
25
95
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param {
|
|
29
|
-
* @
|
|
30
|
-
* @param {AccountParam} [params.account] - Optional account. Can be an address string or an object with an `address` property. Defaults to the signer's address (EIP-7702).
|
|
31
|
-
* @param {object} [params.paymaster] - Optional paymaster configuration with policy IDs.
|
|
32
|
-
* @returns {SmartWalletClient} A wallet client extended with smart wallet actions.
|
|
96
|
+
* Solana-specific adapters are in `@alchemy/wallet-apis/solana`.
|
|
97
|
+
*
|
|
98
|
+
* @param {CreateSolanaSmartWalletClientParams} params - Solana client configuration
|
|
99
|
+
* @returns {SolanaSmartWalletClient} A Solana smart wallet client with Solana smart wallet actions
|
|
33
100
|
*/
|
|
34
|
-
export
|
|
101
|
+
export function createSmartWalletClient(
|
|
102
|
+
params: CreateSolanaSmartWalletClientParams,
|
|
103
|
+
): SolanaSmartWalletClient;
|
|
104
|
+
export function createSmartWalletClient(
|
|
105
|
+
params: CreateSmartWalletClientParams,
|
|
106
|
+
): SmartWalletClient | SolanaSmartWalletClient {
|
|
107
|
+
if (isSolanaParams(params)) {
|
|
108
|
+
return createSolanaClient(params);
|
|
109
|
+
}
|
|
110
|
+
return createEvmClient(params);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ── EVM path ────────────────────────────────────────────────────────────
|
|
114
|
+
|
|
115
|
+
function createEvmClient({
|
|
35
116
|
signer,
|
|
36
117
|
transport,
|
|
37
118
|
chain,
|
|
38
119
|
account,
|
|
39
120
|
paymaster,
|
|
40
|
-
}:
|
|
121
|
+
}: CreateEvmSmartWalletClientParams): SmartWalletClient {
|
|
41
122
|
const _policyIds = [
|
|
42
|
-
...(paymaster?.policyId ? [paymaster
|
|
123
|
+
...(paymaster?.policyId ? [paymaster.policyId] : []),
|
|
43
124
|
...(paymaster?.policyIds ?? []),
|
|
44
125
|
];
|
|
45
126
|
|
|
@@ -60,4 +141,36 @@ export const createSmartWalletClient = ({
|
|
|
60
141
|
owner: signer,
|
|
61
142
|
}))
|
|
62
143
|
.extend(smartWalletActions);
|
|
63
|
-
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ── Solana path ─────────────────────────────────────────────────────────
|
|
147
|
+
|
|
148
|
+
function createSolanaClient({
|
|
149
|
+
signer,
|
|
150
|
+
transport,
|
|
151
|
+
chain,
|
|
152
|
+
account,
|
|
153
|
+
paymaster,
|
|
154
|
+
}: CreateSolanaSmartWalletClientParams): SolanaSmartWalletClient {
|
|
155
|
+
const _policyIds = paymaster?.policyId ? [paymaster.policyId] : [];
|
|
156
|
+
|
|
157
|
+
const _account = account ?? signer.address;
|
|
158
|
+
|
|
159
|
+
const _chain = SOLANA_CHAINS[chain];
|
|
160
|
+
if (!_chain) {
|
|
161
|
+
throw new BaseError(`Unsupported Solana chain: ${chain}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return createClient({
|
|
165
|
+
transport,
|
|
166
|
+
chain: _chain,
|
|
167
|
+
name: "alchemySolanaSmartWalletClient",
|
|
168
|
+
})
|
|
169
|
+
.extend(() => ({
|
|
170
|
+
policyIds: _policyIds,
|
|
171
|
+
internal: createInternalState(),
|
|
172
|
+
owner: signer,
|
|
173
|
+
solanaAccount: _account,
|
|
174
|
+
}))
|
|
175
|
+
.extend(solanaSmartWalletActions);
|
|
176
|
+
}
|
|
@@ -109,7 +109,7 @@ export type SmartWalletActions = {
|
|
|
109
109
|
export const smartWalletActions = (
|
|
110
110
|
client: InnerWalletApiClient,
|
|
111
111
|
): SmartWalletActions => ({
|
|
112
|
-
// Alchemy
|
|
112
|
+
// Alchemy actions.
|
|
113
113
|
requestAccount: (params) => requestAccount(client, params),
|
|
114
114
|
prepareCalls: (params) => prepareCalls(client, params),
|
|
115
115
|
listAccounts: (params) => listAccounts(client, params),
|
|
@@ -122,7 +122,7 @@ export const smartWalletActions = (
|
|
|
122
122
|
grantPermissions: (params) => grantPermissions(client, params),
|
|
123
123
|
getCapabilities: (params) => getCapabilities(client, params),
|
|
124
124
|
undelegateAccount: (params) => undelegateAccount(client, params),
|
|
125
|
-
// Viem
|
|
125
|
+
// Viem actions.
|
|
126
126
|
getCallsStatus: (params) => getCallsStatus(client, params),
|
|
127
127
|
waitForCallsStatus: (params) => waitForCallsStatus(client, params),
|
|
128
128
|
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { InnerSolanaWalletApiClient } from "../types.js";
|
|
2
|
+
import {
|
|
3
|
+
prepareCalls,
|
|
4
|
+
type SolanaPrepareCallsParams,
|
|
5
|
+
type SolanaPrepareCallsResult,
|
|
6
|
+
} from "../actions/solana/prepareCalls.js";
|
|
7
|
+
import {
|
|
8
|
+
signPreparedCalls,
|
|
9
|
+
type SolanaSignPreparedCallsParams,
|
|
10
|
+
type SolanaSignPreparedCallsResult,
|
|
11
|
+
} from "../actions/solana/signPreparedCalls.js";
|
|
12
|
+
import {
|
|
13
|
+
sendPreparedCalls,
|
|
14
|
+
type SolanaSendPreparedCallsParams,
|
|
15
|
+
type SolanaSendPreparedCallsResult,
|
|
16
|
+
} from "../actions/solana/sendPreparedCalls.js";
|
|
17
|
+
import {
|
|
18
|
+
sendCalls,
|
|
19
|
+
type SolanaSendCallsParams,
|
|
20
|
+
type SolanaSendCallsResult,
|
|
21
|
+
} from "../actions/solana/sendCalls.js";
|
|
22
|
+
import {
|
|
23
|
+
getCallsStatus,
|
|
24
|
+
type SolanaGetCallsStatusParams,
|
|
25
|
+
type SolanaGetCallsStatusResult,
|
|
26
|
+
} from "../actions/solana/getCallsStatus.js";
|
|
27
|
+
import {
|
|
28
|
+
waitForCallsStatus,
|
|
29
|
+
type SolanaWaitForCallsStatusParams,
|
|
30
|
+
type SolanaWaitForCallsStatusResult,
|
|
31
|
+
} from "../actions/solana/waitForCallsStatus.js";
|
|
32
|
+
|
|
33
|
+
export type SolanaSmartWalletActions = {
|
|
34
|
+
prepareCalls: (
|
|
35
|
+
params: SolanaPrepareCallsParams,
|
|
36
|
+
) => Promise<SolanaPrepareCallsResult>;
|
|
37
|
+
signPreparedCalls: (
|
|
38
|
+
params: SolanaSignPreparedCallsParams,
|
|
39
|
+
) => Promise<SolanaSignPreparedCallsResult>;
|
|
40
|
+
sendPreparedCalls: (
|
|
41
|
+
params: SolanaSendPreparedCallsParams,
|
|
42
|
+
) => Promise<SolanaSendPreparedCallsResult>;
|
|
43
|
+
sendCalls: (params: SolanaSendCallsParams) => Promise<SolanaSendCallsResult>;
|
|
44
|
+
getCallsStatus: (
|
|
45
|
+
params: SolanaGetCallsStatusParams,
|
|
46
|
+
) => Promise<SolanaGetCallsStatusResult>;
|
|
47
|
+
waitForCallsStatus: (
|
|
48
|
+
params: SolanaWaitForCallsStatusParams,
|
|
49
|
+
) => Promise<SolanaWaitForCallsStatusResult>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const solanaSmartWalletActions = (
|
|
53
|
+
client: InnerSolanaWalletApiClient,
|
|
54
|
+
): SolanaSmartWalletActions => ({
|
|
55
|
+
prepareCalls: (params) => prepareCalls(client, params),
|
|
56
|
+
signPreparedCalls: (params) => signPreparedCalls(client, params),
|
|
57
|
+
sendPreparedCalls: (params) => sendPreparedCalls(client, params),
|
|
58
|
+
sendCalls: (params) => sendCalls(client, params),
|
|
59
|
+
// Note that status actions from Viem don't work since the chain ID is not hex.
|
|
60
|
+
getCallsStatus: (params) => getCallsStatus(client, params),
|
|
61
|
+
waitForCallsStatus: (params) => waitForCallsStatus(client, params),
|
|
62
|
+
});
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { Address, Prettify } from "viem";
|
|
2
|
-
import type {
|
|
1
|
+
import type { Address, Hex, Prettify } from "viem";
|
|
2
|
+
import type { InnerWalletApiClient } from "../../types.ts";
|
|
3
3
|
import {
|
|
4
4
|
fromRpcCapabilities,
|
|
5
5
|
mergeClientCapabilities,
|
|
6
6
|
toRpcCapabilities,
|
|
7
7
|
type PrepareCallsCapabilities,
|
|
8
|
-
type WithCapabilities,
|
|
9
8
|
} from "../../utils/capabilities.js";
|
|
10
9
|
import { resolveAddress, type AccountParam } from "../../utils/resolve.js";
|
|
11
10
|
import { wallet_requestQuote_v0 as MethodSchema } from "@alchemy/wallet-api-types/rpc";
|
|
@@ -13,24 +12,40 @@ import {
|
|
|
13
12
|
methodSchema,
|
|
14
13
|
encode,
|
|
15
14
|
decode,
|
|
16
|
-
type MethodParams,
|
|
17
15
|
type MethodResponse,
|
|
18
16
|
} from "../../utils/schema.js";
|
|
19
17
|
|
|
20
18
|
const schema = methodSchema(MethodSchema);
|
|
21
|
-
type BaseRequestQuoteV0Params = MethodParams<typeof MethodSchema>;
|
|
22
19
|
type RequestQuoteV0Response = MethodResponse<typeof MethodSchema>;
|
|
23
20
|
|
|
21
|
+
type SwapAmountParams =
|
|
22
|
+
| { fromAmount: bigint; minimumToAmount?: never }
|
|
23
|
+
| { fromAmount?: never; minimumToAmount: bigint };
|
|
24
|
+
|
|
25
|
+
type SwapChainParams =
|
|
26
|
+
| {
|
|
27
|
+
toChainId?: never;
|
|
28
|
+
postCalls?: Array<{ to: Address; data?: Hex; value?: bigint }>;
|
|
29
|
+
}
|
|
30
|
+
| { toChainId: number; postCalls?: never };
|
|
31
|
+
|
|
32
|
+
type SwapExecutionParams =
|
|
33
|
+
| { returnRawCalls?: false; capabilities?: PrepareCallsCapabilities }
|
|
34
|
+
| { returnRawCalls: true; capabilities?: never };
|
|
35
|
+
|
|
24
36
|
/**
|
|
25
37
|
* Parameters accepted by the experimental `requestQuoteV0` action.
|
|
26
38
|
*/
|
|
27
39
|
export type RequestQuoteV0Params = Prettify<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
{
|
|
41
|
+
fromToken: Address;
|
|
42
|
+
toToken: Address;
|
|
43
|
+
slippage?: bigint;
|
|
44
|
+
account?: AccountParam;
|
|
45
|
+
chainId?: number;
|
|
46
|
+
} & SwapAmountParams &
|
|
47
|
+
SwapChainParams &
|
|
48
|
+
SwapExecutionParams
|
|
34
49
|
>;
|
|
35
50
|
|
|
36
51
|
/** The modifiedRequest in client format: `account` instead of `from`, SDK capabilities. */
|
package/src/exports/index.ts
CHANGED
|
@@ -29,16 +29,20 @@ export type * from "../actions/undelegateAccount.js";
|
|
|
29
29
|
export { undelegateAccount } from "../actions/undelegateAccount.js";
|
|
30
30
|
|
|
31
31
|
// Decorators.
|
|
32
|
-
export type
|
|
32
|
+
export type { SmartWalletActions } from "../decorators/smartWalletActions.js";
|
|
33
33
|
export { smartWalletActions } from "../decorators/smartWalletActions.js";
|
|
34
34
|
|
|
35
35
|
// Client.
|
|
36
36
|
export type {
|
|
37
|
-
BaseWalletClient,
|
|
38
|
-
SignerClient,
|
|
39
37
|
SmartWalletClient,
|
|
38
|
+
SolanaSmartWalletClient,
|
|
39
|
+
SolanaSigner,
|
|
40
40
|
} from "../types.js";
|
|
41
|
-
export type
|
|
41
|
+
export type {
|
|
42
|
+
CreateEvmSmartWalletClientParams,
|
|
43
|
+
CreateSolanaSmartWalletClientParams,
|
|
44
|
+
CreateSmartWalletClientParams,
|
|
45
|
+
} from "../client.js";
|
|
42
46
|
export { createSmartWalletClient } from "../client.js";
|
|
43
47
|
|
|
44
48
|
// Transport.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Actions.
|
|
2
|
+
export type * from "../actions/solana/prepareCalls.js";
|
|
3
|
+
export { prepareCalls } from "../actions/solana/prepareCalls.js";
|
|
4
|
+
export type * from "../actions/solana/signPreparedCalls.js";
|
|
5
|
+
export { signPreparedCalls } from "../actions/solana/signPreparedCalls.js";
|
|
6
|
+
export type * from "../actions/solana/sendPreparedCalls.js";
|
|
7
|
+
export { sendPreparedCalls } from "../actions/solana/sendPreparedCalls.js";
|
|
8
|
+
export type * from "../actions/solana/sendCalls.js";
|
|
9
|
+
export { sendCalls } from "../actions/solana/sendCalls.js";
|
|
10
|
+
export type * from "../actions/solana/getCallsStatus.js";
|
|
11
|
+
export { getCallsStatus } from "../actions/solana/getCallsStatus.js";
|
|
12
|
+
export type * from "../actions/solana/waitForCallsStatus.js";
|
|
13
|
+
export { waitForCallsStatus } from "../actions/solana/waitForCallsStatus.js";
|
|
14
|
+
|
|
15
|
+
// Decorator.
|
|
16
|
+
export type { SolanaSmartWalletActions } from "../decorators/solanaSmartWalletActions.js";
|
|
17
|
+
export { solanaSmartWalletActions } from "../decorators/solanaSmartWalletActions.js";
|
|
18
|
+
|
|
19
|
+
// Errors.
|
|
20
|
+
export { SolanaSignerError } from "../adapters/SolanaSignerError.js";
|
|
21
|
+
|
|
22
|
+
// Adapters.
|
|
23
|
+
export { fromKeypair } from "../adapters/fromKeypair.js";
|
|
24
|
+
export type { SolanaKeypairSigner } from "../adapters/fromKeypair.js";
|
|
25
|
+
export { fromKitSigner } from "../adapters/fromKitSigner.js";
|
|
26
|
+
export type { SolanaTransactionPartialSigner } from "../adapters/fromKitSigner.js";
|
|
27
|
+
export { fromWalletAdapter } from "../adapters/fromWalletAdapter.js";
|
|
28
|
+
export type { WalletAdapterSigner } from "../adapters/fromWalletAdapter.js";
|
|
29
|
+
export { fromWalletStandard } from "../adapters/fromWalletStandard.js";
|
|
30
|
+
export type {
|
|
31
|
+
WalletStandardWallet,
|
|
32
|
+
WalletStandardAccount,
|
|
33
|
+
} from "../adapters/fromWalletStandard.js";
|
|
34
|
+
|
|
35
|
+
// Types.
|
|
36
|
+
export type { SolanaSigner, SolanaSmartWalletClient } from "../types.js";
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WalletServerViemRpcSchema } from "@alchemy/wallet-api-types/rpc";
|
|
2
|
+
import type { SolanaChainId } from "@alchemy/wallet-api-types";
|
|
2
3
|
import type {
|
|
3
4
|
Account,
|
|
4
5
|
Address,
|
|
@@ -12,31 +13,61 @@ import type {
|
|
|
12
13
|
} from "viem";
|
|
13
14
|
import type { InternalState } from "./internal";
|
|
14
15
|
import type { SmartWalletActions } from "./decorators/smartWalletActions";
|
|
16
|
+
import type { SolanaSmartWalletActions } from "./decorators/solanaSmartWalletActions";
|
|
15
17
|
|
|
16
18
|
export type BaseWalletClient<
|
|
17
19
|
TExtend extends { [key: string]: unknown } | undefined =
|
|
18
20
|
| { [key: string]: unknown }
|
|
19
21
|
| undefined,
|
|
22
|
+
TAccount extends Account | undefined = JsonRpcAccount<Address>,
|
|
20
23
|
> = Client<
|
|
21
24
|
Transport<"alchemyHttp">,
|
|
22
25
|
Chain,
|
|
23
|
-
|
|
26
|
+
TAccount,
|
|
24
27
|
WalletServerViemRpcSchema,
|
|
25
28
|
TExtend
|
|
26
29
|
>;
|
|
27
30
|
|
|
28
|
-
export type InnerWalletApiClient = BaseWalletClient<{
|
|
29
|
-
internal: InternalState | undefined; // undefined if you want to skip using an internal cache
|
|
30
|
-
owner: SmartWalletSigner;
|
|
31
|
-
policyIds?: string[];
|
|
32
|
-
}>;
|
|
33
|
-
|
|
34
31
|
export type SignerClient = WalletClient<Transport, Chain | undefined, Account>;
|
|
35
32
|
|
|
36
33
|
export type SmartWalletSigner = LocalAccount | SignerClient;
|
|
37
34
|
|
|
38
35
|
export type SmartWalletClient = BaseWalletClient<SmartWalletActions>;
|
|
39
36
|
|
|
37
|
+
export type SolanaSmartWalletClient = BaseWalletClient<
|
|
38
|
+
SolanaSmartWalletActions & { solanaAccount: string },
|
|
39
|
+
undefined
|
|
40
|
+
>;
|
|
41
|
+
|
|
42
|
+
/** Solana signer interface. Takes serialized tx bytes, returns signed serialized tx bytes. */
|
|
43
|
+
export interface SolanaSigner {
|
|
44
|
+
address: string;
|
|
45
|
+
signTransaction(input: {
|
|
46
|
+
transaction: Uint8Array;
|
|
47
|
+
[key: string]: unknown;
|
|
48
|
+
}): Promise<{ signedTransaction: Uint8Array }>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface SolanaChainDef extends Chain {
|
|
52
|
+
solanaChainId: SolanaChainId;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type InnerWalletApiClient = BaseWalletClient<{
|
|
56
|
+
internal: InternalState | undefined;
|
|
57
|
+
owner: SmartWalletSigner;
|
|
58
|
+
policyIds?: string[];
|
|
59
|
+
}>;
|
|
60
|
+
|
|
61
|
+
export type InnerSolanaWalletApiClient = BaseWalletClient<
|
|
62
|
+
{
|
|
63
|
+
internal: InternalState | undefined;
|
|
64
|
+
owner: SolanaSigner;
|
|
65
|
+
solanaAccount: string;
|
|
66
|
+
policyIds?: string[];
|
|
67
|
+
},
|
|
68
|
+
undefined
|
|
69
|
+
>;
|
|
70
|
+
|
|
40
71
|
export type OptionalChainId<T> = T extends { chainId: number }
|
|
41
72
|
? Omit<T, "chainId"> & { chainId?: number | undefined }
|
|
42
73
|
: T;
|
package/src/utils/assertions.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import type { Client, LocalAccount } from "viem";
|
|
2
|
-
import type {
|
|
1
|
+
import type { Chain, Client, LocalAccount } from "viem";
|
|
2
|
+
import type {
|
|
3
|
+
InnerWalletApiClient,
|
|
4
|
+
InnerSolanaWalletApiClient,
|
|
5
|
+
SignerClient,
|
|
6
|
+
SolanaChainDef,
|
|
7
|
+
} from "../types.js";
|
|
3
8
|
import { BaseError } from "@alchemy/common";
|
|
4
9
|
|
|
5
10
|
/**
|
|
@@ -14,6 +19,12 @@ export function isSmartWalletClient(
|
|
|
14
19
|
return client.name === "alchemySmartWalletClient" && "owner" in client;
|
|
15
20
|
}
|
|
16
21
|
|
|
22
|
+
export function isSolanaClient(
|
|
23
|
+
client: Client,
|
|
24
|
+
): client is InnerSolanaWalletApiClient {
|
|
25
|
+
return client.name === "alchemySolanaSmartWalletClient" && "owner" in client;
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
/**
|
|
18
29
|
* Assertion function that throws an error if the client is not an Alchemy Smart Wallet Client.
|
|
19
30
|
* After this function returns successfully, TypeScript will narrow the client type.
|
|
@@ -31,6 +42,10 @@ export function assertSmartWalletClient(
|
|
|
31
42
|
}
|
|
32
43
|
}
|
|
33
44
|
|
|
45
|
+
export function isSolanaChain(chain: Chain): chain is SolanaChainDef {
|
|
46
|
+
return "solanaChainId" in chain;
|
|
47
|
+
}
|
|
48
|
+
|
|
34
49
|
export function isLocalAccount(
|
|
35
50
|
signer: LocalAccount | SignerClient,
|
|
36
51
|
): signer is LocalAccount {
|