Proposal details

#49 Upgrade Smart Wallet to support NFTs

Passed

Upgrade WalletFactory to support arbitrary ERTP assets such as NFTs. Based on [agoric-upgrade-11wf](https://github.com/Agoric/agoric-sdk/releases/tag/agoric-upgrade-11wf) e669bb12f560d84f7fc017abda49d3dd6d5cee17 See also [Upgrade Smart Wallet to support NFTs](https://community.agoric.com/t/upgrade-smart-wallet-to-support-nfts/461) discussion.

Submit time: 18 Sep 2023, 19:37

Details

Voting period

100.00%
18 Sep 2023, 19:3721 Sep 2023, 19:37

Core Eval Proposal

  • Title

    Upgrade Smart Wallet to support NFTs

  • Type

    CoreEvalProposal

  • Data
    {
    "evals":[
    0:{
    "jsonPermits":"{ "consume": { "contractKits": "to upgrade walletFactory using its adminFacet", "instancePrivateArgs": "to get privateArgs for walletFactory", "agoricNames": true, "board": true, "chainStorage": true, "agoricNamesAdmin": "makeCoreProposalBehavior", "vatAdminSvc": "makeCoreProposalBehavior", "zoe": "makeCoreProposalBehavior" }, "instance": { "consume": { "walletFactory": true, "provisionPool": true } }, "evaluateBundleCap": "makeCoreProposalBehavior", "installation": { "produce": "makeCoreProposalBehavior" }, "modules": { "utils": { "runModuleBehaviors": "makeCoreProposalBehavior" } } }"
    "jsCode":"// This is generated by writeCoreProposal; please edit! /* eslint-disable */ const manifestBundleRef = {bundleID:"b1-e229e4bb6c8720016d92116e3dccaebec20a43699d5547a1c815f8710985ba897e825cbe4cd5b80c1d9d674f086bcaf3981b82a0d5546a095542c14174d5f942"}; const getManifestCall = harden([ "getManifestForUpgrade", { walletFactoryRef: { bundleID: "b1-fa06290e58e5df0b5e8e26ebf7926176770bee5d32f42bcaa62bb77737955a8d9da2922760e644e26643b36ec3118c3c0d546f2af4faf717fdb6ae1fb36773d0", }, }, ]); const overrideManifest = { publishAgoricBrandsDisplayInfo: { consume: { agoricNames: true, board: true, chainStorage: true, }, }, upgradeWalletFactory: { consume: { contractKits: "to upgrade walletFactory using its adminFacet", instancePrivateArgs: "to get privateArgs for walletFactory", }, instance: { consume: { provisionPool: true, walletFactory: true, }, }, }, }; // Make the behavior the completion value. (({ manifestBundleRef, getManifestCall, overrideManifest, E, log = console.info, restoreRef: overrideRestoreRef, }) => { const { entries, fromEntries } = Object; // deeplyFulfilled is a bit overkill for what we need. const shallowlyFulfilled = async obj => { if (!obj) { return obj; } const ents = await Promise.all( entries(obj).map(async ([key, valueP]) => { const value = await valueP; return [key, value]; }), ); return fromEntries(ents); }; /** @param {ChainBootstrapSpace & BootstrapPowers & { evaluateBundleCap: any }} allPowers */ const behavior = async allPowers => { // NOTE: If updating any of these names extracted from `allPowers`, you must // change `permits` above to reflect their accessibility. const { consume: { vatAdminSvc, zoe, agoricNamesAdmin }, evaluateBundleCap, installation: { produce: produceInstallations }, modules: { utils: { runModuleBehaviors }, }, } = allPowers; const [exportedGetManifest, ...manifestArgs] = getManifestCall; const defaultRestoreRef = async ref => { // extract-proposal.js creates these records, and bundleName is // the name under which the bundle was installed into // config.bundles const p = ref.bundleName ? E(vatAdminSvc).getBundleIDByName(ref.bundleName) : ref.bundleID; const bundleID = await p; const label = bundleID.slice(0, 8); return E(zoe).installBundleID(bundleID, label); }; const restoreRef = overrideRestoreRef || defaultRestoreRef; // Get the on-chain installation containing the manifest and behaviors. console.info('evaluateBundleCap', { manifestBundleRef, exportedGetManifest, vatAdminSvc, }); let bcapP; if ('bundleName' in manifestBundleRef) { bcapP = E(vatAdminSvc).getNamedBundleCap(manifestBundleRef.bundleName); } else { bcapP = E(vatAdminSvc).getBundleCap(manifestBundleRef.bundleID); } const bundleCap = await bcapP; const manifestNS = await evaluateBundleCap(bundleCap); console.error('execute', { exportedGetManifest, behaviors: Object.keys(manifestNS), }); const { manifest, options: rawOptions, installations: rawInstallations, } = await manifestNS[exportedGetManifest]( harden({ restoreRef }), ...manifestArgs, ); // Await references in the options or installations. const [options, installations] = await Promise.all( [rawOptions, rawInstallations].map(shallowlyFulfilled), ); // Publish the installations for behavior dependencies. const installAdmin = E(agoricNamesAdmin).lookupAdmin('installation'); await Promise.all( entries(installations || {}).map(([key, value]) => { produceInstallations[key].resolve(value); return E(installAdmin).update(key, value); }), ); // Evaluate the manifest for our behaviors. return runModuleBehaviors({ allPowers, behaviors: manifestNS, manifest: overrideManifest || manifest, makeConfig: (name, _permit) => { log('coreProposal:', name); return { options }; }, }); }; // Make the behavior the completion value. return behavior; })({ manifestBundleRef, getManifestCall, overrideManifest, E }); "
    }
    ]
    "@type":"/agoric.swingset.CoreEvalProposal"
    }