/
transferSol.ts
161 lines (145 loc) · 3.55 KB
/
transferSol.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import { PublicKey, SystemProgram } from '@solana/web3.js';
import { SendAndConfirmTransactionResponse } from '../../rpcModule';
import type { Metaplex } from '@/Metaplex';
import {
assertSol,
Operation,
OperationHandler,
OperationScope,
Signer,
SolAmount,
useOperation,
} from '@/types';
import { TransactionBuilder, TransactionBuilderOptions } from '@/utils';
// -----------------
// Operation
// -----------------
const Key = 'TransferSolOperation' as const;
/**
* Transfers some SOL from one account to another.
*
* ```ts
* await metaplex
* .system()
* .transferSol({
* to: new PublicKey("..."),
* amount: sol(1.5),
* };
* ````
*
* @group Operations
* @category Constructors
*/
export const transferSolOperation = useOperation<TransferSolOperation>(Key);
/**
* @group Operations
* @category Types
*/
export type TransferSolOperation = Operation<
typeof Key,
TransferSolInput,
TransferSolOutput
>;
/**
* @group Operations
* @category Inputs
*/
export type TransferSolInput = {
/**
* The account that sends the SOLs as a Signer.
*
* @defaultValue `metaplex.identity()`
*/
from?: Signer;
/** The address of the account that receives the SOLs. */
to: PublicKey;
/** The amount of SOLs to send. */
amount: SolAmount;
/**
* Base public key to use to derive the funding account address.
*
* @defaultValue Defaults to not being used.
*/
basePubkey?: PublicKey;
/**
* Seed to use to derive the funding account address.
*
* @defaultValue Defaults to not being used.
*/
seed?: string;
};
/**
* @group Operations
* @category Outputs
*/
export type TransferSolOutput = {
/** The blockchain response from sending and confirming the transaction. */
response: SendAndConfirmTransactionResponse;
};
/**
* @group Operations
* @category Handlers
*/
export const transferSolOperationHandler: OperationHandler<TransferSolOperation> =
{
async handle(
operation: TransferSolOperation,
metaplex: Metaplex,
scope: OperationScope
): Promise<TransferSolOutput> {
const builder = transferSolBuilder(metaplex, operation.input, scope);
return builder.sendAndConfirm(metaplex, scope.confirmOptions);
},
};
// -----------------
// Builder
// -----------------
/**
* @group Transaction Builders
* @category Inputs
*/
export type TransferSolBuilderParams = Omit<
TransferSolInput,
'confirmOptions'
> & {
/** A key to distinguish the instruction that transfers some SOL. */
instructionKey?: string;
};
/**
* Transfers some SOL from one account to another.
*
* ```ts
* const transactionBuilder = metaplex
* .system()
* .builders()
* .transferSol({
* to: new PublicKey("..."),
* amount: sol(1.5),
* });
* ````
*
* @group Transaction Builders
* @category Constructors
*/
export const transferSolBuilder = (
metaplex: Metaplex,
params: TransferSolBuilderParams,
options: TransactionBuilderOptions = {}
): TransactionBuilder => {
const { programs, payer = metaplex.rpc().getDefaultFeePayer() } = options;
const { from = metaplex.identity(), to, amount, basePubkey, seed } = params;
assertSol(amount);
return TransactionBuilder.make()
.setFeePayer(payer)
.add({
instruction: SystemProgram.transfer({
fromPubkey: from.publicKey,
toPubkey: to,
lamports: amount.basisPoints.toNumber(),
...(basePubkey ? { basePubkey, seed } : {}),
programId: metaplex.programs().getSystem(programs).address,
}),
signers: [from],
key: params.instructionKey ?? 'transferSol',
});
};