If I control my planet in bridge with a Hardware Wallet and I lose my master ticket can I regenerate it?
Answer
Azimuth has 5 separate public keys that are set. The Ownership address is set to the address inside your hardware wallet. If you rekey the master key you will
Answering
I logged into bridge with my Ethereum Wallet and learned I can transfer my master ticket. This text was pulled from bridge UI
Reticketing is the process of generating a completely fresh wallet and transferring ownership of your point to that wallet.
Beware, this resets your proxy addresses; if you're using smart contracts, this might break them! It will also change your networking keys!
This rekey's the entire planet, let's find what this does in the smart contracts. Let's find what the code is doing
- bridge/src/views/UrbitID/ResetKeys/ResetExecute.tsx at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge
- Line 181
reticketPointBetweenWallets
from 'lib/reticket';
- Line 181
- bridge/src/lib/reticket.js at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge
// configure management proxy
const managementTx = azimuth.ecliptic.setManagementProxy(
contracts,
point,
toWallet.management.keys.address
);
managementTx.gas = GAS_LIMITS.SET_PROXY;
// set spawn & voting proxies situationally
// skip this step if reticketing an L1 point with L2-migrated spawn proxy
let txs = [transferTmpTx, keysTx, managementTx];
if (!isPlanet(point) && doSetSpawnProxy) {
const spawnTx = azimuth.ecliptic.setSpawnProxy(
contracts,
point,
toWallet.spawn.keys.address
);
spawnTx.gas = GAS_LIMITS.SET_PROXY;
txs.push(spawnTx);
}
if (isGalaxy(point)) {
const votingTx = azimuth.ecliptic.setVotingProxy(
contracts,
point,
toWallet.voting.keys.address
);
votingTx.gas = GAS_LIMITS.SET_PROXY;
txs.push(votingTx);
}
// transfer configured point to user's new wallet
const transferFinalTx = azimuth.ecliptic.transferPoint(
contracts,
point,
toWallet.ownership.keys.address,
false
);
transferFinalTx.gas = GAS_LIMITS.TRANSFER;
txs.push(transferFinalTx);
//
// finalizing & signing transactions
//
progress(TRANSACTION_PROGRESS.SIGNING);
Seems like 3 transactions here
Performing Transfer for ~tartem-milteb
- transferPoint ran first
- Configure Keys second
- SetManagementProxy third
- TransferPoint ran again
Why did we get 4 transactions?
transferPoint is called twice, I wonder if we actually needed to call it?
//TODO no harm done if we already owned it, but should still get a bool arg
// for skipping this, if it isn't too big a burden for callers
const transferTmpTx = azimuth.ecliptic.transferPoint(
contracts,
point,
fromWallet.address,
false
);
transferTmpTx.gas = GAS_LIMITS.TRANSFER;
...
// transfer configured point to user's new wallet
const transferFinalTx = azimuth.ecliptic.transferPoint(
contracts,
point,
toWallet.ownership.keys.address,
false
);
transferFinalTx.gas = GAS_LIMITS.TRANSFER;
txs.push(transferFinalTx);
//
// finalizing & signing transactions
//
What is this fromWallet and toWallet?
} else {
await reticketPointBetweenWallets({
fromWallet: need.wallet(wallet),
fromWalletType: walletType,
fromWalletHdPath: walletHdPath,
toWallet: newWallet.value.wallet,
point: point,
web3: need.web3(web3),
contracts: need.contracts(contracts),
networkType,
onUpdate: handleUpdate,
nextRevision: networkRevision + 1,
txnSigner,
txnSender,
});
}
} catch (err) {
console.error(err);
setGeneralError(err);
I just went and generated the public key from the Management Proxy, that is the management address
You can use this script with ethers@5.3 to generate the address
const ethers = require('ethers');
async function main() {
// Load the mnemonic from the .env file
let mnemonic = "MNEMONIC GOES HERE"
let mnemonic_path = process.env.MNEMONIC_PATH
if (mnemonic_path == ''){
mnemonic_path = "m/44'/60'/0'/0"
}
if (!mnemonic) {
throw new Error('MNEMONIC not found in .env file');
}
const wallet = ethers.Wallet.fromMnemonic(mnemonic, mnemonic_path);
console.log('Wallet address:', wallet.address);
}
main().catch((error) => {
console.error('Error:', error);
process.exit(1);
});
Alright so why do we have a MASTER TICKET and a MANAGEMENT PROXY
I just realized that the ethereum is inside both the MASTER TICKET and MANAGEMENT PROXY
It is pretty clear what transactions in the Bridge code set the Master Ticket and Management Ticket,
It appears I can change ownership and management keys without having to reset network keys, interesting.
What does this azimuth.ecliptic.setSpawnProxy
do
Gotta check azimuth-js
Seems that setSpawnProxy just calls the smart contract, let's take a look at the source code
azimuth/contracts/Azimuth.sol at bcf1d7bcf64cd73a3688434feb786be39a116819 · urbit/azimuth
Oh this makes sense now take a look at this
azimuth/contracts/Azimuth.sol at bcf1d7bcf64cd73a3688434feb786be39a116819 · urbit/azimuth
struct Deed
{
// owner: address that owns this point
//
address owner;
// managementProxy: 0, or another address with the right to perform
// low-impact, managerial operations on this point
//
address managementProxy;
// spawnProxy: 0, or another address with the right to spawn children
// of this point
//
address spawnProxy;
// votingProxy: 0, or another address with the right to vote as this point
//
address votingProxy;
// transferProxy: 0, or another address with the right to transfer
// ownership of this point
//
address transferProxy;
}
Source: Urbit HD Wallet • Reference • developers.urbit.org
There are 5 Wallets, now why do we 5 keys.
Owner, Transfer, Spawn, Management, Voting
I feel like we only need
Owner, Management, and Voting
I reset my master ticket, so that reset everything
Ownership and Management are the only keys accessible from Bridge
So what does this Transfer key do, what does this Voting key do, what does this Spawn key do?
Wait so how do I reset networking keys?
- bridge/src/views/UrbitOS/NetworkKeys.tsx at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge
azimuth.ecliptic.configureKeys
is used to set network keys
Oh SPAWN is used to MOONS
So what is the difference between MANAGEMENT and TRANSFER
You want a backup key, if OWNERSHIP seed is lost TRANSFER seed can allow the point to be reset. THE OWNERSHIP seed can CHANGE the TRANSFER address but not vice versa.
Okay I understand the 5 different keys now
2023-07-15T02:09:42-04:00
So Tlon, why does bridge set the spawn address when we are not going to be generating any moons any time soon!?!?!?!
Wait what is the Spawn address actually set to?
- bridge/src/lib/reticket.js at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge
- toWallet is a variable input into this an exported function named
reticketPointBetweenWallets
- toWallet is a variable input into this an exported function named
- bridge/src/views/UrbitID/ResetKeys/ResetExecute.tsx at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge
await reticketPointBetweenWallets({
fromWallet: need.wallet(wallet),
fromWalletType: walletType,
fromWalletHdPath: walletHdPath,
toWallet: f.value.wallet,
point: point,
web3: need.web3(web3),
contracts: need.contracts(contracts),
networkType,
onUpdate: handleUpdate,
nextRevision: networkRevision + 1,
txnSigner,
txnSender,
});
well this toWallet thing generates a wallet for it
What is this toWallet!?!?!
interface ResetExecuteProps {
// a Maybe<UrbitWallet>
newWallet: any;
// a useState setter, accepts Maybe<UrbitWallet>
setNewWallet: (args: any) => {};
}
ResetExecute is called in bridge/src/views/UrbitID/ResetKeys.jsx at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge ResetKeys.jsx has a setNewWallet function _setNewWallet seems to be something We have a provider managing state
import { LocalRouterProvider } from 'lib/LocalRouter';
bridge/src/lib/LocalRouter.ts at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge Shit it is empty Remember providers have functions to update state
Finally found how the EVM addresses are generated bridge/src/lib/walletgen.ts at d49bb352dfd3219f6d7934530c6dc2cb3adc3f55 · urbit/bridge
Oh the wallet generation is all in a separate repo, urbit/urbit-key-generation: Key derivation and HD wallet generation functions for Urbit