Finding the wallet for a given DID

I have a wee bit of code that attempts to find the wallet associated with a did. Notice the comment “matching on wallet name - perhaps needs to be more authoritative?”

Turns out that, yes something more is needed.

I notice that the data object of the wallet has an "origin_coin property and one of the entries in its parent_info array has an item with the hex version of the did string.

Is the authoritative way to find a did wallet from a did to find the DID type wallet that meets that criteria?

original implementation matching on name

async function getDidWalletCoin(wallet, fullNode, did) {
    // get all did wallets
    const response = await wallet.get_wallets({ type: 8, }); // DISTRIBUTED_ID
    // matching on wallet name - perhaps needs to be more authoritative?
    const didWallets = response.wallets.filter(wallet => wallet.name === `DID ${did}` || wallet.name === did);
    if (didWallets.length === 0) {
        throw new Error(`no did wallet found for ${did}`);
    }

    // get the did object associated with the wallet and lookup its coin record
    const didResponse = await wallet.did_get_did({ wallet_id: didWallets[0].id });
    const getCoinRecordResponse = await fullNode.get_coin_record_by_name({ name: didResponse.coin_id });

    return getCoinRecordResponse.coin_record.coin;
}

updated implementation searching for parent_info

async function getDidWalletCoin(wallet, fullNode, did, did_id) {
    // get all did wallets
    const response = await wallet.get_wallets({ type: 8, }); // DISTRIBUTED_ID

    // find the wallet that has a matching name or parent_info
    const didWallets = response.wallets.filter((wallet) => {
        if (wallet.name === `DID ${did}` || wallet.name === did) {
            // quick exit for default naming
            return true;
        }

        if (_.isNil(wallet.data)) {
            return false;
        }

        const data = JSON.parse(wallet.data);
        if (_.isNil(data.parent_info)) {
            return false;
        }

        const matchingItem = data.parent_info.find(item => item[0] === did_id);
        return matchingItem !== undefined;
    });
    if (didWallets.length === 0) {
        throw new Error(`no did wallet found for ${did}`);
    }

    // get the did object associated with the wallet and lookup its coin record
    const didResponse = await wallet.did_get_did({ wallet_id: didWallets[0].id });
    const getCoinRecordResponse = await fullNode.get_coin_record_by_name({ name: didResponse.coin_id });

    return getCoinRecordResponse.coin_record.coin;
}

Unfortunately, it seems like there’s no RPC for just straight up getting a wallet by it’s DID ID, so yeah I think your best bet is to get all of the wallets of the DID type and then filter it by calling did_get_did on each until you find the matching ID.

Thanks @quexington. Made me realize I was going the long way around only to land on did_get_did.

Simplified implementation:

async function getDidWalletCoin(wallet, fullNode, did) {
    // get all did wallets and find the one that matches the did
    const response = await wallet.get_wallets({ type: 8 }); // DISTRIBUTED_ID

    for await (const didWallet of response.wallets) {
        const didResponse = await wallet.did_get_did({
            wallet_id: didWallet.id,
        });

        if (didResponse.my_did === did) {
            const getCoinRecordResponse =
                await fullNode.get_coin_record_by_name({
                    name: didResponse.coin_id,
                });

            return getCoinRecordResponse.coin_record.coin;
        }
    }

    throw new Error(`no did wallet found for ${did}`);
}