@@ -26,7 +26,7 @@ import {
2626 Value ,
2727 Vkey ,
2828 Vkeywitness ,
29- Vkeywitnesses ,
29+ Vkeywitnesses , Withdrawals ,
3030} from '@emurgo/cardano-serialization-lib-nodejs' ;
3131import { Service } from "./service" ;
3232import { AdaStakeOptions , InternalAdaConfig , UTXO } from "../types/ada" ;
@@ -35,6 +35,7 @@ import {
3535 BlockfrostServerError ,
3636} from "@blockfrost/blockfrost-js" ;
3737import { InvalidIntegration , InvalidSignature } from "../errors/integrations" ;
38+ import { ADDRESSES } from "../globals" ;
3839
3940const CARDANO_PARAMS = {
4041 COINS_PER_UTXO_WORD : '34482' ,
@@ -44,6 +45,7 @@ const CARDANO_PARAMS = {
4445 MIN_FEE_B : '155381' ,
4546 POOL_DEPOSIT : '500000000' ,
4647 KEY_DEPOSIT : '2000000' ,
48+ MIN_UTXO_VALUE_ADA_ONLY : 1000000 ,
4749} ;
4850
4951export class AdaService extends Service {
@@ -66,8 +68,8 @@ export class AdaService extends Service {
6668 options ?: AdaStakeOptions ,
6769 ) : Promise < Transaction > {
6870 const poolId = options ?. poolId ? options . poolId :
69- this . testnet ? 'pool1xjt9ylq7rvsd2mxf6njkzhrkhgjzrtflz039vxs66ntvv82rdky' :
70- 'pool10rdglgh4pzvkf936p2m669qzarr9dusrhmmz9nultm3uvq4eh5k' ;
71+ this . testnet ? ADDRESSES . ada . testnet . poolId :
72+ ADDRESSES . ada . mainnet . poolId ;
7173
7274 try {
7375 const utxos = await this . getUtxos ( walletAddress ) ;
@@ -115,6 +117,62 @@ export class AdaService extends Service {
115117 }
116118 }
117119
120+ /**
121+ * Craft ada withdraw rewards transaction
122+ * @param walletAddress wallet delegating that will receive the rewards
123+ * @param amountToWithdraw amount of rewards to withdraw, if not provided all rewards are withdrawn
124+ */
125+ async craftWithdrawRewardsTx (
126+ walletAddress : string ,
127+ amountToWithdraw ?: number ,
128+ ) : Promise < Transaction > {
129+
130+
131+ try {
132+ const utxos = await this . getUtxos ( walletAddress ) ;
133+ const address = await this . client . addresses ( walletAddress ) ;
134+ if ( ! address . stake_address ) {
135+ throw Error ( 'No stake address' ) ;
136+ }
137+
138+ const stakeKeyHash = await this . getStakeKeyHash ( address . stake_address ) ;
139+ if ( ! stakeKeyHash ) {
140+ throw Error ( 'Could not hash stake key' ) ;
141+ }
142+
143+ const withdrawals = Withdrawals . new ( ) ;
144+ const rewardAddress = RewardAddress . from_address ( Address . from_bech32 ( address . stake_address ) ) ;
145+
146+ if ( ! rewardAddress ) {
147+ throw Error ( 'Could not retrieve rewards address' ) ;
148+ }
149+
150+ const rewardsHistory = await this . client . accountsRewardsAll ( address . stake_address ) ;
151+ let totalRewards : number = 0 ;
152+ for ( const rewards of rewardsHistory ) {
153+ totalRewards += Number ( rewards . amount ) ;
154+ }
155+
156+ const amountToWithdrawLovelace = amountToWithdraw ? this . adaToLovelace ( amountToWithdraw . toString ( ) ) : totalRewards . toString ( ) ;
157+ withdrawals . insert ( rewardAddress , BigNum . from_str ( amountToWithdrawLovelace ) ) ;
158+
159+ let walletBalance = 0 ;
160+ for ( const utxo of utxos ) {
161+ if ( utxo . amount . length > 0 && utxo . amount [ 0 ] . unit === 'lovelace' ) {
162+ walletBalance += Number ( utxo . amount [ 0 ] . quantity ) ;
163+ }
164+ }
165+ // Not sure about this value (might need to be BALANCE + REWARDS + FEES)
166+ const outAmount = ( CARDANO_PARAMS . MIN_UTXO_VALUE_ADA_ONLY + totalRewards ) . toString ( ) ;
167+ const outputs = this . prepareTx ( outAmount , walletAddress ) ;
168+
169+ const tx = await this . buildTx ( walletAddress , utxos , outputs , null , withdrawals ) ;
170+ return tx ;
171+ } catch ( error ) {
172+ throw error ;
173+ }
174+ }
175+
118176 /**
119177 * Prepare outputs (destination addresses and amounts) for a transaction
120178 * @param lovelaceValue
@@ -140,9 +198,16 @@ export class AdaService extends Service {
140198 * @param utxos
141199 * @param outputs
142200 * @param certificates
201+ * @param withdrawals
143202 * @private
144203 */
145- private async buildTx ( changeAddress : string , utxos : UTXO , outputs : TransactionOutputs , certificates : Certificates | null = null ) {
204+ private async buildTx (
205+ changeAddress : string ,
206+ utxos : UTXO ,
207+ outputs : TransactionOutputs ,
208+ certificates : Certificates | null = null ,
209+ withdrawals : Withdrawals | null = null ,
210+ ) : Promise < Transaction > {
146211 const txBuilder = TransactionBuilder . new (
147212 TransactionBuilderConfigBuilder . new ( )
148213 . fee_algo (
@@ -165,6 +230,10 @@ export class AdaService extends Service {
165230 txBuilder . set_certs ( certificates ) ;
166231 }
167232
233+ if ( withdrawals ) {
234+ txBuilder . set_withdrawals ( withdrawals ) ;
235+ }
236+
168237 // Inputs
169238 const lovelaceUtxos = utxos . filter (
170239 ( u : any ) => ! u . amount . find ( ( a : any ) => a . unit !== 'lovelace' ) ,
0 commit comments