Recurrent transfer documentation
documentation·@howo·
0.000 HBDRecurrent transfer documentation
Recurrent transfers can be a little tricky to understand, they do not in fact work like a series of `transfer` operations. So I thought I would write a doc to explain all of the details.  <center> art by dall-e </center> ## The recurrent transfer operation The recurrent transfer operation takes a lot of parameters, here's an example in javascript: Transfers assets, such as HIVE or HBD, from one account to another. ```js hive.broadcast.recurrentTransfer(wif, from, to, amount, memo, recurrence, executions, extensions, function(err, result) { console.log(err, result); }); ``` |Parameter|Description|Datatype|Notes| |---|---|---|---| |wif|Active private key for the `from` account|string|| |from|Account name to take asset from|string|No leading @ symbol| |to|Account name to place asset into|string|No leading @ symbol| |amount|Amount of of asset to transfer|string|"X.XXX ASSET" must have 3 decimal places. e.g. "5.150 HBD"| |recurrence|How often will the payment be triggered|integer|e.g. 48 - unit: hours| |executions|The times the recurrent payment will be executed|integer|e.g. 10 - one tranfer per recurrence| |extensions|Unused at the moment |array| you should just input `[]` here |function()|Your callback|function|| Some additional details: - The first recurrent transfer will be executed immediately, so the `from` account must have at least the `amount` in its account. - `executions` needs to be at least 2, otherwise there is no point in creating a recurrent transfer as it will expire instantly - The recurrence has to be at least **24**, aka 24 hours - The maximum time a recurrent transfer can exists is **730 days** (2 years), so if your `recurrence` is every 6 months, the max `executions` you'll be able to set will be `4` - You cannot recurrent transfer Hive power - The max `memo` size is **2048** (same for regular transfer memos) - You cannot execute recurrent transfers to yourself. If you really want to you could setup a recurrent transfer to another account that has a recurrent transfer set back to you: Bob -> Alice -> Bob ## Validating that a recurrent transfer has been executed Two virtual operations have been added to track recurrent transfer execution: ### fill_recurrent_transfer It's a virtual operation that indicates that a recurrent transfer has been executed correctly. | Field | Type | Description | |--------------------|----------------------|-----------------------------------------------------------------------| | from | string | The user that initiated the transfer (source of `amount`). | | to | string | The user that is the target of the transfer (receiver of `amount`). | | amount | string | The amount of HIVE or HBD transferred in the current iteration. | | memo | string | A memo attached to the transfer. | | remaining_executions | uint16 | The number of remaining pending transfers. | You can see a live example in this block: https://hiveblocks.com/b/55391310 ### failed_recurrent_transfer It can happen that a recurrent transfer fails if the `from` account does not have enough tokens to transfer when the recurrent transfer reaches it's due date. When this happens, the blockchain pushes a `failed_recurrent_transfer`: | Field | Type | Description | |---------------------------|----------------------|--------------------------------------------------------------------------| | from | string | The user that initiated the transfer (source of `amount` that has not enough balance to cover it). | | to | string | The user that is the target of the transfer (would be receiver of `amount`, but no transfer actually happened). | | amount | string | The amount of HIVE or HBD that was scheduled for transfer in the current iteration but failed. | | memo | string | A memo attached to the transfer. | | consecutive_failures | string | The number of failed iterations. | | remaining_executions | uint16 | The number of remaining pending transfers. | | deleted | bool | `true` if the whole recurrent transfer was discontinued due to too many consecutive failures. | Some details: if there are too many `consecutive_failures`, the blockchain will delete the recurrent transfer. At that point the `deleted` flag will be set to true to indicate of the deletion. Right now the threshold is set to **10** consecutive failed payments. In case of failure, the recurrent transfer will not be retried. This means that if your recurrent transfer is set to execute weekly, the next time the recurrent transfer would execute is in a week. ## Recurrent transfers in practice: Here's a few examples to help you get started: ## javascript ``` const hive = require('@hiveio/hive-js'); async function recurrent_transfer(wif, from, to, amount, memo, recurrence, executions) { return new Promise(resolve => { hive.broadcast.recurrentTransfer(wif, from, to, amount, memo, recurrence, executions, [], function (err, result) { console.log(err, result); return resolve("=") }); }) } // Send 2 HBD from bob to initminer every week for a month await recurrent_transfer("5KS4VfGeaWLVG76P4QcBUiJD...", "bob", "initminer", "2.000 HBD", "this is a memo", 7, 4) ``` The best way to track the execution of recurrent transfers is to get the account history and filter on the two virtual operations: ``` const { ChainTypes, makeBitMaskFilter } = require('@hiveio/hive-js/lib/auth/serializer') const op = ChainTypes.operations const walletOperationsBitmask = makeBitMaskFilter([ // op.recurrent_transfer, op.fill_recurrent_transfer, op.failed_recurrent_transfer, ]) hive.api.getAccountHistory("bob", 200, 200, ...walletOperationsBitmask, function(err, result) { console.log(err, result); }); ``` Output is an array with all the operations: ``` [ [ 6, { "trx_id": "0000000000000000000000000000000000000000", "block": 75, "trx_in_block": 4294967295, "op_in_trx": 2, "virtual_op": true, "timestamp": "2023-01-04T19:02:06", "op": [ "fill_recurrent_transfer", { "from": "initminer", "to": "bob", "amount": "1.100 TBD", "memo": "this is a memo", "remaining_executions": 0 } ] } ], [ 7, { "trx_id": "0000000000000000000000000000000000000000", "block": 75, "trx_in_block": 4294967295, "op_in_trx": 2, "virtual_op": true, "timestamp": "2023-01-04T19:02:06", "op": [ "failed_recurrent_transfer", { "from": "bob", "to": "alice", "amount": "2.000 TBD", "memo": "this is a memo", "consecutive_failures": 10, "remaining_executions": 1, "deleted": true } ] } ] ] ``` ## cli_wallet Create a 1 HBD transfer from alice to bob every 24 hours for 5 days: `recurrent_transfer alice bob "1.000 HBD" "This is a memo" 24 5 true true` get the ops in the account history to track completion: `get_account_history bob 20 20` example output: ``` # BLOCK # TRX ID OPERATION DETAILS --------------------------------------------------------------------------------------------------- 1 11 2ad56e183d3498dcdf2ec3a187a8ed9b7499a4e3 account_created {"new_account_name":"bob","creator":"initminer","initial_vesting_shares":"0.000000 VESTS","initial_delegation":"0.000000 VESTS"} 2 36 f843d208a773b5abb8bc9370caf228ad94868d4d recurrent_transfer {"from":"initminer","to":"bob","amount":"1.100 HBD","memo":"this is a memo","recurrence":1,"executions":200,"extensions":[]} 3 36 0000000000000000000000000000000000000000 fill_recurrent_transfer {"from":"initminer","to":"bob","amount":"1.100 HBD","memo":"this is a memo","remaining_executions":199} 4 46 36322b5d787f77a40ac6037b20f3d0118b6284e8 recurrent_transfer {"from":"initminer","to":"bob","amount":"1.100 HBD","memo":"this is a memo","recurrence":1,"executions":2,"extensions":[]} 5 55 0000000000000000000000000000000000000000 fill_recurrent_transfer {"from":"initminer","to":"bob","amount":"1.100 HBD","memo":"this is a memo","remaining_executions":1} 6 75 0000000000000000000000000000000000000000 fill_recurrent_transfer {"from":"initminer","to":"bob","amount":"1.100 HBD","memo":"this is a memo","remaining_executions":0} 7 76 18d281ec590f09e31a719eaa6fdd1a1f95d0d76e transfer_to_vesting {"from":"initminer","to":"bob","amount":"5000.000 TESTS"} 8 76 18d281ec590f09e31a719eaa6fdd1a1f95d0d76e transfer_to_vesting_completed {"from_account":"initminer","to_account":"bob","hive_vested":"5000.000 TESTS","vesting_shares_received":"129.595700 VESTS"} 9 78 0159c7ebb95385accf979afddc3eba15b17d770a recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","recurrence":1,"executions":10,"extensions":[]} 10 78 0000000000000000000000000000000000000000 fill_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","remaining_executions":9} 11 97 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":1,"remaining_executions":8,"deleted":false} 12 117 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":2,"remaining_executions":7,"deleted":false} 13 137 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":3,"remaining_executions":6,"deleted":false} 14 157 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":4,"remaining_executions":5,"deleted":false} 15 177 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":5,"remaining_executions":4,"deleted":false} 16 197 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":6,"remaining_executions":3,"deleted":false} 17 217 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":7,"remaining_executions":2,"deleted":false} 18 237 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":8,"remaining_executions":1,"deleted":false} 19 257 0000000000000000000000000000000000000000 failed_recurrent_transfer {"from":"bob","to":"initminer","amount":"2.000 HBD","memo":"this is a memo","consecutive_failures":9,"remaining_executions":0,"deleted":false} ```
👍 kevinwong, joeyarnoldvn, yangyanje, kat.eli, simba, arconite, clau-de-sign, mrwang, mochita, nurhayati, mind.force, noelyss, freebornsociety, sciencevienna, rbm, cst90, solominer, potpourry, wolffeys, recoveryinc, samrisso, tomtothetom, cugel, liz.writes, movement19, psicologiaexpres, dying, pishio, tipsybosphorus, djblendah, gerber, ezzy, exyle, steem.leo, mice-k, dcityrewards, rafalski, cakemonster, blocktvnews, shitsignals, jeanlucsr, felander, blockbrothers, unconditionalove, bestboom, dlike, bobby.madagascar, followjohngalt, samsemilia7, determine, permaculturedude, haikusailor, steemindian, kgswallet, triplea.bot, tiffin, beta500, leo.syndication, one.life, lividseagulls, therealyme, invest2learn, ribary, kgsupport, dpend.active, sketching, jelly13, hivechat, photo-hive-five, leodis, hungryharish, hungryanu, drricksanchez, soufianechakrouf, coolguy123, alexa.art, tarazkp, blockchainyouth, the-table, lordb, radiv, babytarazkp, bgmoha, firinmahlazer, maxer27, lemouth, feedmytwi, trafalgar, dhimmel, omstavan, ioioioioi, portugalcoin, digital.mine, likwid, htotoo, traf, promobot, raindrop, kgakakillerg, augusto-cordova, julesquirin, sachingeorge, acantoni, zuun.net, xtrafalgar, artefactoestudio, ripperone, kingscrown, enjar, kiemis, abdulmath, boatymcboatface, theshell, sirjaxxy, smon-joa, kendewitt, youraverageguy, cryptodonator, biglove, howo, buzzbee, podg3, thehouse, silverquest, almightygrim, andreadancer, choco11oreo11, emaillisahere, jussbren, jack0, tommys.shop, kattycrochet, dnrxgwp2021, ahad222, tiger55, sdoyle, marshalmugi, jackmiller, meanbees, thehive, yeswecan, acta, hucksbucks, plainoldme, zirochka, cardtrader, steemychicken1, edb, kosimoos, m-san, huckleberrie, ambiguity, ribalinux, ammar0344, kraken99, robotics101, tristan-muller, macchiata, tommyl33, penguinpablo, cryptonized, funnyman, alphacore, hungrybear, guysellars, jacuzzi, varunpinto, arthursiq5, drsensor, fw206, appreciator, emeka4, xappreciator, bluemist, sunsea, anikekirsten, myfreshes, zeesh, actioncats, gabilan55, adedayoolumide, noalys, elgatoshawua, hexagono6, power-kappe, aprasad2325, yoieuqudniram, quycmf8, femcy-willcy, sovebrito, lyamalfonzo23, detlev, x30, dynamicrypto, ravenmus1c, sima369, leighscotford, lucianav, trouvaille, fotomaglys, wendy0520, inciter, tdogvoid, rosepac, desro, coolsurfer, happyfrog420-new, thereikiforest, hive.friends, auracraft, cryptictruth, brianoflondon, hivehydra, podping, cryptoccshow, pocketrocket, theb0red1, gtg, techslut, kggymlife, cryptodive, beerlover, elyelma, treasuree, sperosamuel15, amitsharma, gadrian, jinvest, hecates, geeklania, ga38jem, marius19, avaris, amerlin, paulriq, aceh.potrait, kaiggue, hivecluster, mullmull, beco132, heron-ua, ariuss, shahabshah, sudeon, ivet, nathen007, abouttodie, shyrybovich, borislavzlatanov, thevil, diodao, olaunlimited, igormuba, perfilbrasil, eliel, valor2s, wilfredojgf, shanibeer, cpufronz, theplan, titusfrost, borran, thrasher666, phortun, onlavu, steemik, bil.prag, francescomai, tamaralovelace, preparedwombat, bitcoinflood, asgarth, tex73110, efmm, confundidos, doncustom, mirandaserver, arabisouri, ahmedsy, josewil, empato365, jdike, datsir, cesinfenianos, photographercr, silversaver888, fredrikaa, neoado, jenthoughts, arraydrunkhappy, wiseagent, linita, danyst1ne, bonzopoe, etselec23, n1t0, mangowambo, sofs-su, luvinlyf, yensesa, saintopic, djoi, ppjose, masterroshi, jimmy406, goldenunicorn, uche-nna, mirel0510, bennie-13, rainbrella, pexpresiones, isabelpena, karlin, oizaguirres, yolmare, karolines, junior182, marinmex, celi130, obandoduarte, sevalo13, josemoises, hermaryrc, ernick, hojaraskita, leninbracho50, petronila, rodyservi, nacarid, jadams2k18, axeltheartist, alcidescadiz, nildasalazar, yosmandiaz, andreseloy581, yiobri, arytonhive, louis88, louis.random, wend1go, larus, holdonla, rocinanteprimo, alenox, oliverschmid, tadesaurius2323, ponpase, franzpaulie, financialmodel, cashheavensilver, softworld, santigs, oflyhigh, wherein, lnakuma, celeste413, cnstm, lianjingmedia, likuang007, zerofive, violator101, foggwulf101, starrouge, becca-mac, deepresearch, techguard, jphamer1, sharkthelion, some-asshole, volatilegains, hjrrodriguez, thecuriousfool, melcaya, mintrawa, drag33, rauti, lauti, mcedric, aswita, name0, ikrahch, stealthtrader, saqibhashmi222, terrain, yabapmatt, al-leonardo, rammargarita, a-quarius, themonetaryfew, foxlatam, elikast, sisterhood2, zaibkang, zdigital222, cryptonewzcazter, manniman, watchlist, novillain, abelfotografia, itsmiessyonpeakd, creacioneslelys, art.fluo, xclie, ablaze, ausbitbank, valenpba, tikatarot, aliriera, sofibofi, peakd, mozzie5, omarrojas, yulilemus02, ace108, tanzeelasarfraz, zzzinnn,