1
- import { Indexer , helpers , Address , Script , RPC , hd , config , commons , BI , Transaction } from "@ckb-lumos/lumos" ;
1
+ import { Indexer , helpers , Address , Script , RPC , hd , config , commons , BI } from "@ckb-lumos/lumos" ;
2
2
import { BIish } from "@ckb-lumos/bi" ;
3
3
import { payFeeByFeeRate } from "@ckb-lumos/common-scripts/lib/common" ;
4
4
@@ -15,6 +15,50 @@ export type Account = {
15
15
pubKey : string ;
16
16
} ;
17
17
18
+ /**
19
+ * send a transaction to CKB testnet
20
+ * @returns Promise with transaction hash
21
+ */
22
+ export async function transfer ( options : TransactionIO , privateKey : string ) : Promise < { txHash : string ; fee : BI } > {
23
+ // step 1, create an raw transaction
24
+ // an raw transaction have it's inputs and outputs, but no signature
25
+ let txSkeleton = helpers . TransactionSkeleton ( { cellProvider : indexer } ) ;
26
+ for ( const target of options . targets ) {
27
+ // add each outputs to the transaction skeleton
28
+ txSkeleton = await commons . common . transfer (
29
+ txSkeleton ,
30
+ [ options . address ] ,
31
+ target . address ,
32
+ target . capacity ,
33
+ options . address ,
34
+ undefined ,
35
+ { config : AGGRON4 }
36
+ ) ;
37
+ }
38
+
39
+ // these methods add transaction fee to transaction.
40
+ // see the calculate algorithm in https://docs.nervos.org/docs/essays/faq/#how-do-you-calculate-transaction-fee
41
+ txSkeleton = await payFeeByFeeRate ( txSkeleton , [ options . address ] , 1000 , undefined , { config : AGGRON4 } ) ;
42
+
43
+ // step2: sign an transaction
44
+
45
+ txSkeleton = commons . common . prepareSigningEntries ( txSkeleton ) ;
46
+
47
+ // message is the hash of raw transaction
48
+ const message = txSkeleton . get ( "signingEntries" ) . get ( 0 ) ?. message ;
49
+ const signature = hd . key . signRecoverable ( message ! , privateKey ) ;
50
+ const tx = helpers . sealTransaction ( txSkeleton , [ signature ] ) ;
51
+
52
+ // step3: send the transaction to block chain
53
+ const txHash = await rpc . sendTransaction ( tx , "passthrough" ) ;
54
+
55
+ // how about transaction fee? it's just sum(transaction.inputs) - sum(transaction.outputs).
56
+ // the transaction fee will be sent to miner.
57
+
58
+ const transactionFee = getPaidTransactionFee ( txSkeleton ) ;
59
+ return { txHash, fee : transactionFee } ;
60
+ }
61
+
18
62
export const generateAccountFromPrivateKey = ( privKey : string ) : Account => {
19
63
const pubKey = hd . key . privateToPublic ( privKey ) ;
20
64
const args = hd . key . publicKeyToBlake160 ( pubKey ) ;
@@ -42,6 +86,7 @@ export function getPaidTransactionFee(skeleton: helpers.TransactionSkeletonType)
42
86
const outputs = skeleton . outputs . reduce ( ( acc , cur ) => acc . add ( cur . cellOutput . capacity ) , BI . from ( 0 ) ) ;
43
87
return inputs . sub ( outputs ) ;
44
88
}
89
+
45
90
/**
46
91
* fetch all cells and calculate the sum of their capacities
47
92
*/
@@ -55,54 +100,13 @@ export async function fetchAddressBalance(address: string): Promise<BI> {
55
100
return balance ;
56
101
}
57
102
58
- interface Options {
103
+ /**
104
+ * Transaction input and output
105
+ */
106
+ interface TransactionIO {
59
107
targets : {
60
108
address : string ;
61
109
capacity : BIish ;
62
110
} [ ] ;
63
111
address : string ;
64
112
}
65
-
66
- /**
67
- * create an unsigned transaction skeleton which includes several inputs and outputs(for multiple transaction receivers)
68
- */
69
- export async function createUnsignedTxSkeleton ( options : Options ) {
70
- let txSkeleton = helpers . TransactionSkeleton ( { cellProvider : indexer } ) ;
71
- for ( const target of options . targets ) {
72
- txSkeleton = await commons . common . transfer (
73
- txSkeleton ,
74
- [ options . address ] ,
75
- target . address ,
76
- target . capacity ,
77
- options . address ,
78
- undefined ,
79
- { config : AGGRON4 }
80
- ) ;
81
- }
82
-
83
- txSkeleton = await payFeeByFeeRate ( txSkeleton , [ options . address ] , 1000 , undefined , { config : AGGRON4 } ) ;
84
- return txSkeleton ;
85
- }
86
-
87
- /**
88
- * sign a transaction skeleton
89
- * @param txSkeleton unsigned transaction skeleton
90
- * @param privateKey the private key which can unlock input cells
91
- * @returns
92
- */
93
- export function signTransaction ( txSkeleton : helpers . TransactionSkeletonType , privateKey : string ) {
94
- txSkeleton = commons . common . prepareSigningEntries ( txSkeleton ) ;
95
- const message = txSkeleton . get ( "signingEntries" ) . get ( 0 ) ?. message ;
96
- const signature = hd . key . signRecoverable ( message ! , privateKey ) ;
97
- const tx = helpers . sealTransaction ( txSkeleton , [ signature ] ) ;
98
- return tx ;
99
- }
100
-
101
- /**
102
- * send a transaction to CKB testnet
103
- * @returns Promise with transaction hash
104
- */
105
- export async function transfer ( tx : Transaction ) : Promise < string > {
106
- const hash = await rpc . sendTransaction ( tx , "passthrough" ) ;
107
- return hash ;
108
- }
0 commit comments