[{"data":1,"prerenderedAt":1576},["ShallowReactive",2],{"navigation_docs":3,"-operators-hyperlane-multisig-rotation":131,"-operators-hyperlane-multisig-rotation-surround":1571},[4,84,111],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":73},"Operators","i-lucide-server","\u002Foperators","1.operators",[10,15,19,24,29,34,74],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Foperators\u002Fintroduction","1.operators\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":6},"Node Setup","\u002Foperators\u002Fnode-setup","1.operators\u002F2.node-setup",{"title":20,"path":21,"stem":22,"icon":23},"Create a Wallet","\u002Foperators\u002Fcreate-wallet","1.operators\u002F3.create-wallet","i-lucide-wallet",{"title":25,"path":26,"stem":27,"icon":28},"Join as Validator","\u002Foperators\u002Fjoin-as-validator","1.operators\u002F4.join-as-validator","i-lucide-shield-check",{"title":30,"path":31,"stem":32,"icon":33},"Monitoring","\u002Foperators\u002Fmonitoring","1.operators\u002F6.monitoring","i-lucide-activity",{"title":35,"icon":36,"path":37,"stem":38,"children":39,"page":73},"Hyperlane","i-lucide-link","\u002Foperators\u002Fhyperlane","1.operators\u002F7.hyperlane",[40,45,49,53,58,63,68],{"title":41,"path":42,"stem":43,"icon":44},"Hyperlane Agent Keys","\u002Foperators\u002Fhyperlane\u002Fagent-keys","1.operators\u002F7.hyperlane\u002F1.agent-keys","i-lucide-key-round",{"title":46,"path":47,"stem":48,"icon":36},"Hyperlane Setup","\u002Foperators\u002Fhyperlane\u002Fsetup","1.operators\u002F7.hyperlane\u002F2.setup",{"title":50,"path":51,"stem":52,"icon":28},"Run Validators","\u002Foperators\u002Fhyperlane\u002Fvalidators","1.operators\u002F7.hyperlane\u002F3.validators",{"title":54,"path":55,"stem":56,"icon":57},"Warp Token Deployment","\u002Foperators\u002Fhyperlane\u002Fwarp-token","1.operators\u002F7.hyperlane\u002F4.warp-token","i-lucide-arrow-left-right",{"title":59,"path":60,"stem":61,"icon":62},"Testing Warp Route","\u002Foperators\u002Fhyperlane\u002Ftesting-warp-route","1.operators\u002F7.hyperlane\u002F5.testing-warp-route","i-lucide-flask-conical",{"title":64,"path":65,"stem":66,"icon":67},"Join the Multisig","\u002Foperators\u002Fhyperlane\u002Fjoin-multisig","1.operators\u002F7.hyperlane\u002F6.join-multisig","i-lucide-user-plus",{"title":69,"path":70,"stem":71,"icon":72},"Rotate the Multisig","\u002Foperators\u002Fhyperlane\u002Fmultisig-rotation","1.operators\u002F7.hyperlane\u002F7.multisig-rotation","i-lucide-users",false,{"title":75,"icon":76,"path":77,"stem":78,"children":79,"page":73},"Bridge Runbook","i-lucide-list-checks","\u002Foperators\u002Fbridge-runbook","1.operators\u002F8.bridge-runbook",[80],{"title":81,"path":82,"stem":83,"icon":76},"Runbook Validator, Relayer e Multisig","\u002Foperators\u002Fbridge-runbook\u002Fvalidator-relayer-multisig","1.operators\u002F8.bridge-runbook\u002F1.validator-relayer-multisig",{"title":85,"icon":86,"path":87,"stem":88,"children":89,"page":73},"Developers","i-lucide-code","\u002Fdevelopers","2.developers",[90,93,96,101,106],{"title":11,"path":91,"stem":92,"icon":14},"\u002Fdevelopers\u002Fintroduction","2.developers\u002F1.introduction",{"title":20,"path":94,"stem":95,"icon":23},"\u002Fdevelopers\u002Fcreate-wallet","2.developers\u002F2.create-wallet",{"title":97,"path":98,"stem":99,"icon":100},"Faucet","\u002Fdevelopers\u002Ffaucet","2.developers\u002F3.faucet","i-lucide-coins",{"title":102,"path":103,"stem":104,"icon":105},"Chain Parameters","\u002Fdevelopers\u002Fchain-parameters","2.developers\u002F4.chain-parameters","i-lucide-settings",{"title":107,"path":108,"stem":109,"icon":110},"Send Transactions","\u002Fdevelopers\u002Fsend-transactions","2.developers\u002F5.send-transactions","i-lucide-send",{"title":112,"icon":113,"path":114,"stem":115,"children":116,"page":73},"Users","i-lucide-user","\u002Fusers","3.users",[117,120,123,126],{"title":11,"path":118,"stem":119,"icon":14},"\u002Fusers\u002Fintroduction","3.users\u002F1.introduction",{"title":20,"path":121,"stem":122,"icon":23},"\u002Fusers\u002Fcreate-wallet","3.users\u002F2.create-wallet",{"title":97,"path":124,"stem":125,"icon":100},"\u002Fusers\u002Ffaucet","3.users\u002F3.faucet",{"title":127,"path":128,"stem":129,"icon":130},"Staking","\u002Fusers\u002Fstaking","3.users\u002F4.staking","i-lucide-landmark",{"id":132,"title":69,"body":133,"description":1562,"extension":1563,"links":1564,"meta":1565,"navigation":1566,"path":70,"seo":1567,"stem":71,"__hash__":1570},"docs\u002F1.operators\u002F7.hyperlane\u002F7.multisig-rotation.md",{"type":134,"value":135,"toc":1552},"minimark",[136,150,167,172,183,190,219,227,231,280,283,451,455,469,494,833,849,853,859,923,991,1025,1029,1036,1103,1220,1232,1236,1244,1262,1474,1489,1493,1536,1540,1548],[137,138,139,140,144,145,149],"p",{},"This guide covers how the ",[141,142,143],"strong",{},"bridge owner"," changes the validator set or signature threshold of the Hyperlane bridge between BitSong (",[146,147,148],"code",{},"crescendo-1",") and Base Sepolia — for example, to add a new validator or move from a 1-of-1 setup to a 2-of-3 multisig.",[151,152,154,155,158,159,162,163,166],"warning",{"title":153},"Owner-only operation","Every transaction here must be signed with the ",[141,156,157],{},"owner key"," of the bridge (",[146,160,161],{},"--from \u003Cowner-key>","). Operators who only run a validator do not perform these steps — they generate a key and send their EVM address to the owner. See ",[164,165,64],"a",{"href":65}," for the operator side.",[168,169,171],"h2",{"id":170},"why-rotation-is-needed","Why rotation is needed",[137,173,174,175,178,179,182],{},"On Hyperlane the ",[141,176,177],{},"MultisigISM is immutable",": there is no command to add or remove a validator from an existing ISM. To change the set, you ",[141,180,181],{},"create a new MultisigISM"," with the updated validator list and threshold, then re-point the routes that use it.",[137,184,185,186,189],{},"A two-way bridge is secured by ",[141,187,188],{},"two"," ISMs, and both must be updated to fully rotate the set:",[191,192,193,207],"card-group",{},[194,195,198,199,202,203,206],"card",{"icon":196,"title":197},"i-lucide-route","BitSong side — RoutingISM","Verifies ",[141,200,201],{},"Base Sepolia → BitSong"," messages. You create a new MultisigISM on BitSong and re-point the RoutingISM route for domain ",[146,204,205],{},"84532"," to it.",[194,208,198,211,214,215,218],{"icon":209,"title":210},"i-lucide-shield","Base Sepolia side — Static ISM",[141,212,213],{},"BitSong → Base Sepolia"," messages. You deploy a new ",[146,216,217],{},"StaticMessageIdMultisigISM"," via the ISM factory and set it on the HypERC20 contract.",[220,221,222,223,226],"note",{},"If you update only one side, that direction keeps using the old validator set. Update ",[141,224,225],{},"both"," to complete the rotation.",[168,228,230],{"id":229},"prerequisites","Prerequisites",[232,233,234,244,255,277],"ul",{},[235,236,237,238,240,241,243],"li",{},"The bridge ",[141,239,157],{}," on BitSong (for the RoutingISM) and the ",[141,242,157],{}," of the HypERC20 contract on Base Sepolia.",[235,245,246,247,250,251,254],{},"The ",[141,248,249],{},"EVM addresses"," of all validators in the new set, collected from each operator (derived from their key — see ",[164,252,253],{"href":42},"Agent Keys",").",[235,256,257,260,261,268,269,272,273,276],{},[146,258,259],{},"bitsongd",", ",[164,262,267],{"href":263,"rel":264,"target":266},"https:\u002F\u002Fbook.getfoundry.sh\u002Fgetting-started\u002Finstallation",[265],"nofollow","_blank","Foundry"," (",[146,270,271],{},"cast","), and ",[146,274,275],{},"jq",".",[235,278,279],{},"A Base Sepolia RPC and a small amount of Base Sepolia ETH to deploy the EVM-side ISM.",[137,281,282],{},"Set the environment for the live bridge:",[284,285,291],"pre",{"className":286,"code":287,"filename":288,"language":289,"meta":290,"style":290},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export CHAIN_ID=\"crescendo-1\"\nexport REMOTE_DOMAIN=\"84532\"\nexport DENOM=\"utbtsg\"\nexport NODE=\"tcp:\u002F\u002Flocalhost:26657\"\nexport EVM_RPC=\"https:\u002F\u002F\u003Cyour-base-sepolia-rpc>\"\n\n# Live bridge IDs (crescendo-1)\nexport ROUTING_ISM_ID=\"0x726f757465725f69736d00000000000000000000000000010000000000000001\"\nexport HYP_ERC20_ADDR=\"0x27d0F8cBF125995f91407e9E5F70EF52c4412878\"\nexport ISM_FACTORY=\"0xfc6e546510dC9d76057F1f76633FCFfC188CB213\"\n","Terminal","bash","",[146,292,293,319,335,352,369,386,393,400,417,434],{"__ignoreMap":290},[294,295,298,302,306,310,313,316],"span",{"class":296,"line":297},"line",1,[294,299,301],{"class":300},"spNyl","export",[294,303,305],{"class":304},"sTEyZ"," CHAIN_ID",[294,307,309],{"class":308},"sMK4o","=",[294,311,312],{"class":308},"\"",[294,314,148],{"class":315},"sfazB",[294,317,318],{"class":308},"\"\n",[294,320,322,324,327,329,331,333],{"class":296,"line":321},2,[294,323,301],{"class":300},[294,325,326],{"class":304}," REMOTE_DOMAIN",[294,328,309],{"class":308},[294,330,312],{"class":308},[294,332,205],{"class":315},[294,334,318],{"class":308},[294,336,338,340,343,345,347,350],{"class":296,"line":337},3,[294,339,301],{"class":300},[294,341,342],{"class":304}," DENOM",[294,344,309],{"class":308},[294,346,312],{"class":308},[294,348,349],{"class":315},"utbtsg",[294,351,318],{"class":308},[294,353,355,357,360,362,364,367],{"class":296,"line":354},4,[294,356,301],{"class":300},[294,358,359],{"class":304}," NODE",[294,361,309],{"class":308},[294,363,312],{"class":308},[294,365,366],{"class":315},"tcp:\u002F\u002Flocalhost:26657",[294,368,318],{"class":308},[294,370,372,374,377,379,381,384],{"class":296,"line":371},5,[294,373,301],{"class":300},[294,375,376],{"class":304}," EVM_RPC",[294,378,309],{"class":308},[294,380,312],{"class":308},[294,382,383],{"class":315},"https:\u002F\u002F\u003Cyour-base-sepolia-rpc>",[294,385,318],{"class":308},[294,387,389],{"class":296,"line":388},6,[294,390,392],{"emptyLinePlaceholder":391},true,"\n",[294,394,396],{"class":296,"line":395},7,[294,397,399],{"class":398},"sHwdD","# Live bridge IDs (crescendo-1)\n",[294,401,403,405,408,410,412,415],{"class":296,"line":402},8,[294,404,301],{"class":300},[294,406,407],{"class":304}," ROUTING_ISM_ID",[294,409,309],{"class":308},[294,411,312],{"class":308},[294,413,414],{"class":315},"0x726f757465725f69736d00000000000000000000000000010000000000000001",[294,416,318],{"class":308},[294,418,420,422,425,427,429,432],{"class":296,"line":419},9,[294,421,301],{"class":300},[294,423,424],{"class":304}," HYP_ERC20_ADDR",[294,426,309],{"class":308},[294,428,312],{"class":308},[294,430,431],{"class":315},"0x27d0F8cBF125995f91407e9E5F70EF52c4412878",[294,433,318],{"class":308},[294,435,437,439,442,444,446,449],{"class":296,"line":436},10,[294,438,301],{"class":300},[294,440,441],{"class":304}," ISM_FACTORY",[294,443,309],{"class":308},[294,445,312],{"class":308},[294,447,448],{"class":315},"0xfc6e546510dC9d76057F1f76633FCFfC188CB213",[294,450,318],{"class":308},[168,452,454],{"id":453},"_1-create-the-new-multisigism","1. Create the new MultisigISM",[137,456,457,458,461,462,465,466,254],{},"Collect the validator EVM addresses and ",[141,459,460],{},"sort them in ascending byte order",", then create the new ISM with the desired threshold (here, ",[146,463,464],{},"2"," of ",[146,467,468],{},"3",[151,470,472,475,476,479,480,483,484,487,488,487,491,276],{"title":471},"Addresses must be sorted",[146,473,474],{},"create-message-id-multisig"," requires the validator list ",[141,477,478],{},"sorted in ascending byte order"," (hexadecimal, case-insensitive), otherwise it fails with ",[146,481,482],{},"validator addresses are not sorted correctly in ascending order",". Example: ",[146,485,486],{},"0x45ac…"," \u003C ",[146,489,490],{},"0x740b…",[146,492,493],{},"0xdb4e…",[284,495,498],{"className":286,"code":496,"filename":497,"language":289,"meta":290,"style":290},"# Sort V1,V2,V3 ascending (by byte value) before creating the ISM\nexport V1=\"0x\u003Clowest-addr>\"; export V2=\"0x\u003Cmiddle-addr>\"; export V3=\"0x\u003Chighest-addr>\"\n\n# With --gas auto the binary prints \"gas estimate: N\" before the JSON,\n# so extract the txhash defensively rather than piping straight to jq:\nTX_HASH=$(bitsongd tx hyperlane ism create-message-id-multisig \"$V1,$V2,$V3\" 2 \\\n    --from \u003Cowner-key> --keyring-backend test --chain-id $CHAIN_ID --node $NODE \\\n    --gas auto --gas-adjustment 1.5 --fees 10000${DENOM} --output json -y 2>&1 \\\n    | grep -o '\"txhash\":\"[A-Fa-f0-9]*\"' | head -1 | cut -d'\"' -f4)\necho \"TX: $TX_HASH\"\n\nNEW_ISM_ID=$(bitsongd query tx $TX_HASH --output json --node $NODE | \\\n  jq -r 'first(.events[] | select(.type | test(\"MultisigIsm\")) | .attributes[] | select(.key==\"ism_id\") | .value | fromjson)')\necho \"New MultisigISM (2\u002F3): $NEW_ISM_ID\"\n","Owner — Terminal",[146,499,500,505,555,559,564,569,618,653,696,745,761,766,800,818],{"__ignoreMap":290},[294,501,502],{"class":296,"line":297},[294,503,504],{"class":398},"# Sort V1,V2,V3 ascending (by byte value) before creating the ISM\n",[294,506,507,509,512,514,516,519,521,524,527,530,532,534,537,539,541,543,546,548,550,553],{"class":296,"line":321},[294,508,301],{"class":300},[294,510,511],{"class":304}," V1",[294,513,309],{"class":308},[294,515,312],{"class":308},[294,517,518],{"class":315},"0x\u003Clowest-addr>",[294,520,312],{"class":308},[294,522,523],{"class":308},";",[294,525,526],{"class":300}," export",[294,528,529],{"class":304}," V2",[294,531,309],{"class":308},[294,533,312],{"class":308},[294,535,536],{"class":315},"0x\u003Cmiddle-addr>",[294,538,312],{"class":308},[294,540,523],{"class":308},[294,542,526],{"class":300},[294,544,545],{"class":304}," V3",[294,547,309],{"class":308},[294,549,312],{"class":308},[294,551,552],{"class":315},"0x\u003Chighest-addr>",[294,554,318],{"class":308},[294,556,557],{"class":296,"line":337},[294,558,392],{"emptyLinePlaceholder":391},[294,560,561],{"class":296,"line":354},[294,562,563],{"class":398},"# With --gas auto the binary prints \"gas estimate: N\" before the JSON,\n",[294,565,566],{"class":296,"line":371},[294,567,568],{"class":398},"# so extract the txhash defensively rather than piping straight to jq:\n",[294,570,571,574,577,580,583,586,589,592,595,598,601,604,606,609,611,615],{"class":296,"line":388},[294,572,573],{"class":304},"TX_HASH",[294,575,576],{"class":308},"=$(",[294,578,259],{"class":579},"sBMFI",[294,581,582],{"class":315}," tx",[294,584,585],{"class":315}," hyperlane",[294,587,588],{"class":315}," ism",[294,590,591],{"class":315}," create-message-id-multisig",[294,593,594],{"class":308}," \"",[294,596,597],{"class":304},"$V1",[294,599,600],{"class":315},",",[294,602,603],{"class":304},"$V2",[294,605,600],{"class":315},[294,607,608],{"class":304},"$V3",[294,610,312],{"class":308},[294,612,614],{"class":613},"sbssI"," 2",[294,616,617],{"class":304}," \\\n",[294,619,620,623,626,629,632,635,638,641,644,647,650],{"class":296,"line":395},[294,621,622],{"class":315},"    --from",[294,624,625],{"class":308}," \u003C",[294,627,628],{"class":315},"owner-ke",[294,630,631],{"class":304},"y",[294,633,634],{"class":308},">",[294,636,637],{"class":315}," --keyring-backend",[294,639,640],{"class":315}," test",[294,642,643],{"class":315}," --chain-id",[294,645,646],{"class":304}," $CHAIN_ID ",[294,648,649],{"class":315},"--node",[294,651,652],{"class":304}," $NODE \\\n",[294,654,655,658,661,664,667,670,673,676,679,682,685,688,691,694],{"class":296,"line":402},[294,656,657],{"class":315},"    --gas",[294,659,660],{"class":315}," auto",[294,662,663],{"class":315}," --gas-adjustment",[294,665,666],{"class":613}," 1.5",[294,668,669],{"class":315}," --fees",[294,671,672],{"class":613}," 10000",[294,674,675],{"class":308},"${",[294,677,678],{"class":304},"DENOM",[294,680,681],{"class":308},"}",[294,683,684],{"class":315}," --output",[294,686,687],{"class":315}," json",[294,689,690],{"class":315}," -y",[294,692,693],{"class":308}," 2>&1",[294,695,617],{"class":304},[294,697,698,701,704,707,710,713,716,719,722,725,727,730,733,735,737,739,742],{"class":296,"line":419},[294,699,700],{"class":308},"    |",[294,702,703],{"class":579}," grep",[294,705,706],{"class":315}," -o",[294,708,709],{"class":308}," '",[294,711,712],{"class":315},"\"txhash\":\"[A-Fa-f0-9]*\"",[294,714,715],{"class":308},"'",[294,717,718],{"class":308}," |",[294,720,721],{"class":579}," head",[294,723,724],{"class":315}," -1",[294,726,718],{"class":308},[294,728,729],{"class":579}," cut",[294,731,732],{"class":315}," -d",[294,734,715],{"class":308},[294,736,312],{"class":315},[294,738,715],{"class":308},[294,740,741],{"class":315}," -f4",[294,743,744],{"class":308},")\n",[294,746,747,751,753,756,759],{"class":296,"line":436},[294,748,750],{"class":749},"s2Zo4","echo",[294,752,594],{"class":308},[294,754,755],{"class":315},"TX: ",[294,757,758],{"class":304},"$TX_HASH",[294,760,318],{"class":308},[294,762,764],{"class":296,"line":763},11,[294,765,392],{"emptyLinePlaceholder":391},[294,767,769,772,774,776,779,781,784,787,789,792,795,798],{"class":296,"line":768},12,[294,770,771],{"class":304},"NEW_ISM_ID",[294,773,576],{"class":308},[294,775,259],{"class":579},[294,777,778],{"class":315}," query",[294,780,582],{"class":315},[294,782,783],{"class":304}," $TX_HASH ",[294,785,786],{"class":315},"--output",[294,788,687],{"class":315},[294,790,791],{"class":315}," --node",[294,793,794],{"class":304}," $NODE ",[294,796,797],{"class":308},"|",[294,799,617],{"class":304},[294,801,803,806,809,811,814,816],{"class":296,"line":802},13,[294,804,805],{"class":579},"  jq",[294,807,808],{"class":315}," -r",[294,810,709],{"class":308},[294,812,813],{"class":315},"first(.events[] | select(.type | test(\"MultisigIsm\")) | .attributes[] | select(.key==\"ism_id\") | .value | fromjson)",[294,815,715],{"class":308},[294,817,744],{"class":308},[294,819,821,823,825,828,831],{"class":296,"line":820},14,[294,822,750],{"class":749},[294,824,594],{"class":308},[294,826,827],{"class":315},"New MultisigISM (2\u002F3): ",[294,829,830],{"class":304},"$NEW_ISM_ID",[294,832,318],{"class":308},[220,834,835,836,838,839,841,842,844,845,276],{},"A threshold of ",[146,837,464],{}," out of ",[146,840,468],{}," means two signatures are required — the bridge stays operational even if one validator is offline. This ISM verifies the ",[141,843,201],{}," direction; the opposite direction is updated ",[164,846,848],{"href":847},"#4-update-the-base-sepolia-side-ism","on the EVM side",[168,850,852],{"id":851},"_2-remove-the-current-route","2. Remove the current route",[137,854,855,856,858],{},"Find which ISM is currently mapped for the Base Sepolia domain (",[146,857,205],{},"), then remove that mapping from the RoutingISM.",[284,860,862],{"className":286,"code":861,"filename":288,"language":289,"meta":290,"style":290},"ACTIVE_ISM=$(bitsongd query hyperlane ism isms --output json --node $NODE \\\n  | jq -r '.isms[] | select(.\"@type\" | test(\"RoutingISM\")) | .routes[] | select(.domain==84532) | .ism')\necho \"Current ISM (to be replaced): $ACTIVE_ISM\"\n",[146,863,864,890,909],{"__ignoreMap":290},[294,865,866,869,871,873,875,877,879,882,884,886,888],{"class":296,"line":297},[294,867,868],{"class":304},"ACTIVE_ISM",[294,870,576],{"class":308},[294,872,259],{"class":579},[294,874,778],{"class":315},[294,876,585],{"class":315},[294,878,588],{"class":315},[294,880,881],{"class":315}," isms",[294,883,684],{"class":315},[294,885,687],{"class":315},[294,887,791],{"class":315},[294,889,652],{"class":304},[294,891,892,895,898,900,902,905,907],{"class":296,"line":321},[294,893,894],{"class":308},"  |",[294,896,897],{"class":579}," jq",[294,899,808],{"class":315},[294,901,709],{"class":308},[294,903,904],{"class":315},".isms[] | select(.\"@type\" | test(\"RoutingISM\")) | .routes[] | select(.domain==84532) | .ism",[294,906,715],{"class":308},[294,908,744],{"class":308},[294,910,911,913,915,918,921],{"class":296,"line":337},[294,912,750],{"class":749},[294,914,594],{"class":308},[294,916,917],{"class":315},"Current ISM (to be replaced): ",[294,919,920],{"class":304},"$ACTIVE_ISM",[294,922,318],{"class":308},[284,924,926],{"className":286,"code":925,"filename":497,"language":289,"meta":290,"style":290},"bitsongd tx hyperlane ism remove-routing-ism-domain $ROUTING_ISM_ID $REMOTE_DOMAIN \\\n    --from \u003Cowner-key> --keyring-backend test --chain-id $CHAIN_ID --node $NODE \\\n    --gas auto --gas-adjustment 1.5 --fees 10000${DENOM} -y\n",[146,927,928,944,968],{"__ignoreMap":290},[294,929,930,932,934,936,938,941],{"class":296,"line":297},[294,931,259],{"class":579},[294,933,582],{"class":315},[294,935,585],{"class":315},[294,937,588],{"class":315},[294,939,940],{"class":315}," remove-routing-ism-domain",[294,942,943],{"class":304}," $ROUTING_ISM_ID $REMOTE_DOMAIN \\\n",[294,945,946,948,950,952,954,956,958,960,962,964,966],{"class":296,"line":321},[294,947,622],{"class":315},[294,949,625],{"class":308},[294,951,628],{"class":315},[294,953,631],{"class":304},[294,955,634],{"class":308},[294,957,637],{"class":315},[294,959,640],{"class":315},[294,961,643],{"class":315},[294,963,646],{"class":304},[294,965,649],{"class":315},[294,967,652],{"class":304},[294,969,970,972,974,976,978,980,982,984,986,988],{"class":296,"line":337},[294,971,657],{"class":315},[294,973,660],{"class":315},[294,975,663],{"class":315},[294,977,666],{"class":613},[294,979,669],{"class":315},[294,981,672],{"class":613},[294,983,675],{"class":308},[294,985,678],{"class":304},[294,987,681],{"class":308},[294,989,990],{"class":315}," -y\n",[151,992,994,997,998,1001,1002,1005,1006,1008,1009,1012,1013,1016,1017,1020,1021,1024],{"title":993},"set does not overwrite — you must remove first",[146,995,996],{},"set-routing-ism-domain"," ",[141,999,1000],{},"does not overwrite"," a domain that is already mapped (it emits the event but the state does not change). You must ",[141,1003,1004],{},"remove first, then set",". Between the two commands there is a short window where domain ",[146,1007,205],{}," has ",[141,1010,1011],{},"no ISM"," — schedule the rotation during low traffic. To ",[141,1014,1015],{},"roll back",", re-point the route at the previous ISM (",[146,1018,1019],{},"remove"," + ",[146,1022,1023],{},"set"," back to the old ID).",[168,1026,1028],{"id":1027},"_3-set-the-new-route","3. Set the new route",[137,1030,1031,1032,1035],{},"Once the removal is included in a block, point the Base Sepolia route at the ",[141,1033,1034],{},"new"," 2\u002F3 ISM and verify.",[284,1037,1039],{"className":286,"code":1038,"filename":497,"language":289,"meta":290,"style":290},"bitsongd tx hyperlane ism set-routing-ism-domain $ROUTING_ISM_ID $REMOTE_DOMAIN $NEW_ISM_ID \\\n    --from \u003Cowner-key> --keyring-backend test --chain-id $CHAIN_ID --node $NODE \\\n    --gas auto --gas-adjustment 1.5 --fees 10000${DENOM} -y\n",[146,1040,1041,1057,1081],{"__ignoreMap":290},[294,1042,1043,1045,1047,1049,1051,1054],{"class":296,"line":297},[294,1044,259],{"class":579},[294,1046,582],{"class":315},[294,1048,585],{"class":315},[294,1050,588],{"class":315},[294,1052,1053],{"class":315}," set-routing-ism-domain",[294,1055,1056],{"class":304}," $ROUTING_ISM_ID $REMOTE_DOMAIN $NEW_ISM_ID \\\n",[294,1058,1059,1061,1063,1065,1067,1069,1071,1073,1075,1077,1079],{"class":296,"line":321},[294,1060,622],{"class":315},[294,1062,625],{"class":308},[294,1064,628],{"class":315},[294,1066,631],{"class":304},[294,1068,634],{"class":308},[294,1070,637],{"class":315},[294,1072,640],{"class":315},[294,1074,643],{"class":315},[294,1076,646],{"class":304},[294,1078,649],{"class":315},[294,1080,652],{"class":304},[294,1082,1083,1085,1087,1089,1091,1093,1095,1097,1099,1101],{"class":296,"line":337},[294,1084,657],{"class":315},[294,1086,660],{"class":315},[294,1088,663],{"class":315},[294,1090,666],{"class":613},[294,1092,669],{"class":315},[294,1094,672],{"class":613},[294,1096,675],{"class":308},[294,1098,678],{"class":304},[294,1100,681],{"class":308},[294,1102,990],{"class":315},[284,1104,1107],{"className":286,"code":1105,"filename":1106,"language":289,"meta":290,"style":290},"ACTIVE_ISM=$(bitsongd query hyperlane ism isms --output json --node $NODE \\\n  | jq -r '.isms[] | select(.\"@type\" | test(\"RoutingISM\")) | .routes[] | select(.domain==84532) | .ism')\necho \"Active ISM: $ACTIVE_ISM  (expected: $NEW_ISM_ID)\"\n\nbitsongd query hyperlane ism isms --output json --node $NODE \\\n  | jq --arg id \"$ACTIVE_ISM\" '.isms[] | select(.id==$id) | {id, validators, threshold}'\n","Verify",[146,1108,1109,1133,1149,1170,1174,1194],{"__ignoreMap":290},[294,1110,1111,1113,1115,1117,1119,1121,1123,1125,1127,1129,1131],{"class":296,"line":297},[294,1112,868],{"class":304},[294,1114,576],{"class":308},[294,1116,259],{"class":579},[294,1118,778],{"class":315},[294,1120,585],{"class":315},[294,1122,588],{"class":315},[294,1124,881],{"class":315},[294,1126,684],{"class":315},[294,1128,687],{"class":315},[294,1130,791],{"class":315},[294,1132,652],{"class":304},[294,1134,1135,1137,1139,1141,1143,1145,1147],{"class":296,"line":321},[294,1136,894],{"class":308},[294,1138,897],{"class":579},[294,1140,808],{"class":315},[294,1142,709],{"class":308},[294,1144,904],{"class":315},[294,1146,715],{"class":308},[294,1148,744],{"class":308},[294,1150,1151,1153,1155,1158,1160,1163,1165,1168],{"class":296,"line":337},[294,1152,750],{"class":749},[294,1154,594],{"class":308},[294,1156,1157],{"class":315},"Active ISM: ",[294,1159,920],{"class":304},[294,1161,1162],{"class":315},"  (expected: ",[294,1164,830],{"class":304},[294,1166,1167],{"class":315},")",[294,1169,318],{"class":308},[294,1171,1172],{"class":296,"line":354},[294,1173,392],{"emptyLinePlaceholder":391},[294,1175,1176,1178,1180,1182,1184,1186,1188,1190,1192],{"class":296,"line":371},[294,1177,259],{"class":579},[294,1179,778],{"class":315},[294,1181,585],{"class":315},[294,1183,588],{"class":315},[294,1185,881],{"class":315},[294,1187,684],{"class":315},[294,1189,687],{"class":315},[294,1191,791],{"class":315},[294,1193,652],{"class":304},[294,1195,1196,1198,1200,1203,1206,1208,1210,1212,1214,1217],{"class":296,"line":388},[294,1197,894],{"class":308},[294,1199,897],{"class":579},[294,1201,1202],{"class":315}," --arg",[294,1204,1205],{"class":315}," id",[294,1207,594],{"class":308},[294,1209,920],{"class":304},[294,1211,312],{"class":308},[294,1213,709],{"class":308},[294,1215,1216],{"class":315},".isms[] | select(.id==$id) | {id, validators, threshold}",[294,1218,1219],{"class":308},"'\n",[137,1221,246,1222,1225,1226,1229,1230,276],{},[146,1223,1224],{},"validators"," array should list your new set and ",[146,1227,1228],{},"threshold"," should be ",[146,1231,464],{},[168,1233,1235],{"id":1234},"_4-update-the-base-sepolia-side-ism","4. Update the Base Sepolia-side ISM",[137,1237,246,1238,1240,1241,1243],{},[141,1239,213],{}," direction is verified by a ",[146,1242,217],{}," on Base Sepolia, attached to the HypERC20. Deploy a new 2\u002F3 ISM through the official factory and set it on the token.",[137,1245,1246,1247,1250,1251,1254,1255,1258,1259,1261],{},"The ISM can be ",[141,1248,1249],{},"deployed with any funded key"," (even the relayer's KMS key via ",[146,1252,1253],{},"--aws","); only ",[146,1256,1257],{},"setInterchainSecurityModule"," requires the ",[141,1260,157],{}," of the HypERC20.",[284,1263,1265],{"className":286,"code":1264,"filename":288,"language":289,"meta":290,"style":290},"VALS=\"[$V1,$V2,$V3]\"   # same three addresses, sorted\n\n# 1. Predict (read-only) and deploy the 2\u002F3 ISM\nNEW_EVM_ISM=$(cast call $ISM_FACTORY \"deploy(address[],uint8)(address)\" \"$VALS\" 2 --rpc-url $EVM_RPC)\ncast send $ISM_FACTORY \"deploy(address[],uint8)\" \"$VALS\" 2 --private-key \u003Cdeployer-key> --rpc-url $EVM_RPC\necho \"New EVM ISM: $NEW_EVM_ISM\"\n\n# 2. Attach it to the HypERC20 (OWNER key of the HypERC20)\ncast send $HYP_ERC20_ADDR \"setInterchainSecurityModule(address)\" $NEW_EVM_ISM \\\n    --private-key \u003Cowner-evm-key> --rpc-url $EVM_RPC\n\n# 3. Verify\ncast call $HYP_ERC20_ADDR \"interchainSecurityModule()(address)\" --rpc-url $EVM_RPC\n",[146,1266,1267,1297,1301,1306,1345,1386,1400,1404,1409,1428,1446,1450,1455],{"__ignoreMap":290},[294,1268,1269,1272,1274,1276,1279,1281,1283,1285,1287,1289,1292,1294],{"class":296,"line":297},[294,1270,1271],{"class":304},"VALS",[294,1273,309],{"class":308},[294,1275,312],{"class":308},[294,1277,1278],{"class":315},"[",[294,1280,597],{"class":304},[294,1282,600],{"class":315},[294,1284,603],{"class":304},[294,1286,600],{"class":315},[294,1288,608],{"class":304},[294,1290,1291],{"class":315},"]",[294,1293,312],{"class":308},[294,1295,1296],{"class":398},"   # same three addresses, sorted\n",[294,1298,1299],{"class":296,"line":321},[294,1300,392],{"emptyLinePlaceholder":391},[294,1302,1303],{"class":296,"line":337},[294,1304,1305],{"class":398},"# 1. Predict (read-only) and deploy the 2\u002F3 ISM\n",[294,1307,1308,1311,1313,1315,1318,1321,1323,1326,1328,1330,1333,1335,1337,1340,1343],{"class":296,"line":354},[294,1309,1310],{"class":304},"NEW_EVM_ISM",[294,1312,576],{"class":308},[294,1314,271],{"class":579},[294,1316,1317],{"class":315}," call",[294,1319,1320],{"class":304}," $ISM_FACTORY ",[294,1322,312],{"class":308},[294,1324,1325],{"class":315},"deploy(address[],uint8)(address)",[294,1327,312],{"class":308},[294,1329,594],{"class":308},[294,1331,1332],{"class":304},"$VALS",[294,1334,312],{"class":308},[294,1336,614],{"class":613},[294,1338,1339],{"class":315}," --rpc-url",[294,1341,1342],{"class":304}," $EVM_RPC",[294,1344,744],{"class":308},[294,1346,1347,1349,1352,1354,1356,1359,1361,1363,1365,1367,1369,1372,1374,1377,1379,1381,1383],{"class":296,"line":371},[294,1348,271],{"class":579},[294,1350,1351],{"class":315}," send",[294,1353,1320],{"class":304},[294,1355,312],{"class":308},[294,1357,1358],{"class":315},"deploy(address[],uint8)",[294,1360,312],{"class":308},[294,1362,594],{"class":308},[294,1364,1332],{"class":304},[294,1366,312],{"class":308},[294,1368,614],{"class":613},[294,1370,1371],{"class":315}," --private-key",[294,1373,625],{"class":308},[294,1375,1376],{"class":315},"deployer-ke",[294,1378,631],{"class":304},[294,1380,634],{"class":308},[294,1382,1339],{"class":315},[294,1384,1385],{"class":304}," $EVM_RPC\n",[294,1387,1388,1390,1392,1395,1398],{"class":296,"line":388},[294,1389,750],{"class":749},[294,1391,594],{"class":308},[294,1393,1394],{"class":315},"New EVM ISM: ",[294,1396,1397],{"class":304},"$NEW_EVM_ISM",[294,1399,318],{"class":308},[294,1401,1402],{"class":296,"line":395},[294,1403,392],{"emptyLinePlaceholder":391},[294,1405,1406],{"class":296,"line":402},[294,1407,1408],{"class":398},"# 2. Attach it to the HypERC20 (OWNER key of the HypERC20)\n",[294,1410,1411,1413,1415,1418,1420,1423,1425],{"class":296,"line":419},[294,1412,271],{"class":579},[294,1414,1351],{"class":315},[294,1416,1417],{"class":304}," $HYP_ERC20_ADDR ",[294,1419,312],{"class":308},[294,1421,1422],{"class":315},"setInterchainSecurityModule(address)",[294,1424,312],{"class":308},[294,1426,1427],{"class":304}," $NEW_EVM_ISM \\\n",[294,1429,1430,1433,1435,1438,1440,1442,1444],{"class":296,"line":436},[294,1431,1432],{"class":315},"    --private-key",[294,1434,625],{"class":308},[294,1436,1437],{"class":315},"owner-evm-ke",[294,1439,631],{"class":304},[294,1441,634],{"class":308},[294,1443,1339],{"class":315},[294,1445,1385],{"class":304},[294,1447,1448],{"class":296,"line":763},[294,1449,392],{"emptyLinePlaceholder":391},[294,1451,1452],{"class":296,"line":768},[294,1453,1454],{"class":398},"# 3. Verify\n",[294,1456,1457,1459,1461,1463,1465,1468,1470,1472],{"class":296,"line":802},[294,1458,271],{"class":579},[294,1460,1317],{"class":315},[294,1462,1417],{"class":304},[294,1464,312],{"class":308},[294,1466,1467],{"class":315},"interchainSecurityModule()(address)",[294,1469,312],{"class":308},[294,1471,1339],{"class":315},[294,1473,1385],{"class":304},[220,1475,1476,1477,1480,1481,1484,1485,1488],{},"The factory uses CREATE2, so the address from the read-only ",[146,1478,1479],{},"cast call"," is exactly what ",[146,1482,1483],{},"cast send"," deploys. Without this update, BitSong → Base Sepolia would keep being verified by the ",[141,1486,1487],{},"old"," validator set.",[168,1490,1492],{"id":1491},"troubleshooting","Troubleshooting",[1494,1495,1496,1509,1519],"accordion",{},[1497,1498,1501,1502,1504,1505,1508],"accordion-item",{"icon":1499,"label":1500},"i-lucide-circle-help","validator addresses are not sorted correctly","The list for ",[146,1503,474],{}," (and for the EVM ISM factory) must be ",[141,1506,1507],{},"sorted ascending by byte value"," (hex). Reorder the addresses and retry.",[1497,1510,1512,1513,1516,1517,276],{"icon":1499,"label":1511},"set-routing-ism-domain did not change the route","It does not overwrite an already-mapped domain. Run ",[146,1514,1515],{},"remove-routing-ism-domain",", wait for inclusion in a block, then ",[146,1518,996],{},[1497,1520,1522,1525,1526,1529,1530,1532,1533,276],{"icon":1499,"label":1521},"Empty txhash after a transaction (with --gas auto)",[146,1523,1524],{},"--gas auto"," prints ",[146,1527,1528],{},"gas estimate: N"," before the JSON, which breaks a direct ",[146,1531,275],{}," parse. Extract it defensively: ",[146,1534,1535],{},"... -y 2>&1 | grep -o '\"txhash\":\"[A-Fa-f0-9]*\"' | head -1 | cut -d'\"' -f4",[168,1537,1539],{"id":1538},"next-steps","Next Steps",[191,1541,1542,1545],{},[194,1543,1544],{"icon":67,"title":64,"to":65},"The operator side: generate a key and send your validator address to the owner.",[194,1546,1547],{"icon":28,"title":50,"to":51},"Start and operate the validator and relayer agents.",[1549,1550,1551],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":290,"searchDepth":321,"depth":321,"links":1553},[1554,1555,1556,1557,1558,1559,1560,1561],{"id":170,"depth":321,"text":171},{"id":229,"depth":321,"text":230},{"id":453,"depth":321,"text":454},{"id":851,"depth":321,"text":852},{"id":1027,"depth":321,"text":1028},{"id":1234,"depth":321,"text":1235},{"id":1491,"depth":321,"text":1492},{"id":1538,"depth":321,"text":1539},"Owner procedure to change the Hyperlane validator set or threshold on the live BitSong crescendo-1 bridge by creating a new MultisigISM and re-pointing both sides.","md",null,{},{"icon":72},{"title":1568,"description":1569},"Rotate the Hyperlane Multisig - BitSong crescendo-1 Testnet","Create a new 2\u002F3 MultisigISM, re-point the BitSong RoutingISM, and update the Base Sepolia-side ISM to change the validator set on the live Hyperlane bridge.","sxLR6CVvGxQ0I0qF9eX7fXQTGmrX9GA0Bav23tQKAY8",[1572,1574],{"title":64,"path":65,"stem":66,"description":1573,"icon":67,"children":-1},"Join the BitSong Hyperlane validator multisig on an existing bridge using a production AWS setup (KMS signing + S3 checkpoint storage).",{"title":81,"path":82,"stem":83,"description":1575,"icon":76,"children":-1},"Runbook operativo (validato end-to-end) per validator e relayer in AWS KMS + S3, rotazione del multisig 2\u002F3 e test di trasferimento warp sul bridge Hyperlane BitSong (crescendo-1) ↔ Base Sepolia.",1781776026866]