This fixes setting the input value on scan if the component remounts while the scanner is open. No need to use useRef to close the scanner on remount.
Wallets
How to add a new wallet
1. Insert a new row to the WalletTemplate table with which protocols it supports
Example:
INSERT INTO "WalletTemplate" (name, "sendProtocols", "recvProtocols")
VALUES (
    'PHOENIX',
    ARRAY[]::"WalletSendProtocolName"[],
    ARRAY['BOLT12']::"WalletRecvProtocolName"[]
);
2. Customize how the wallet looks on the client via wallets/lib/wallets.json
Example:
{
    // must be same name as wallet template
    "name": "PHOENIX",
    // name to show in client
    "displayName": "Phoenix",
    // image to show in client
    "image": "/path/to/image.png",
    // url (planned) to show in client
    "url": "https://phoenix.acinq.co/"
}
If the wallet supports a lightning address and the domain is different than the url, you can pass an object to url. Here is Zeus as an example:
{
    "templateId": 23,
    "name": "ZEUS",
    "displayName": "Zeus",
    "image": "/wallets/zeus.svg",
    "url": {
        "wallet": "https://zeusln.com/",
        // different domain for lightning address
        "lud16Domain": "zeuspay.com"
    }
},
That's it!
How to add a new protocol
1. Update prisma.schema
- add enum value to 
WalletProtocolNameenum - add enum value to 
WalletRecvProtocolNameorWalletSendProtocolName - add table to store protocol config
 - run 
npx prisma migrate dev --create-only 
Example
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 9a113797..12505333 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -1199,6 +1199,7 @@ enum WalletProtocolName {
   LNC
   CLN_REST
   LND_GRPC
+  BOLT12
 }
 enum WalletSendProtocolName {
@@ -1218,6 +1219,7 @@ enum WalletRecvProtocolName {
   LN_ADDR
   CLN_REST
   LND_GRPC
+  BOLT12
 }
 enum WalletProtocolStatus {
@@ -1288,6 +1290,7 @@ model WalletProtocol {
   walletRecvLightningAddress WalletRecvLightningAddress?
   walletRecvCLNRest          WalletRecvCLNRest?
   walletRecvLNDGRPC          WalletRecvLNDGRPC?
+  walletRecvBolt12           WalletRecvBolt12?
   @@unique(name: "WalletProtocol_walletId_send_name_key", [walletId, send, name])
 }
@@ -1429,3 +1432,12 @@ model WalletRecvLNDGRPC {
   macaroon   String
   cert       String?
 }
+
+model WalletRecvBolt12 {
+  id         Int            @id @default(autoincrement())
+  createdAt  DateTime       @default(now()) @map("created_at")
+  updatedAt  DateTime       @default(now()) @updatedAt @map("updated_at")
+  protocolId Int            @unique
+  protocol   WalletProtocol @relation(fields: [protocolId], references: [id], onDelete: Cascade)
+  offer      String
+}
2. Update migration file
- add required triggers (
wallet_to_jsonbandwallet_clear_vaultif send protocol) to migration file - run 
npx prisma migrate dev 
Example
-- AlterEnum
ALTER TYPE "WalletProtocolName" ADD VALUE 'BOLT12';
-- AlterEnum
ALTER TYPE "WalletRecvProtocolName" ADD VALUE 'BOLT12';
-- CreateTable
CREATE TABLE "WalletRecvBolt12" (
    "id" SERIAL NOT NULL,
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "protocolId" INTEGER NOT NULL,
    "offer" TEXT NOT NULL,
    CONSTRAINT "WalletRecvBolt12_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "WalletRecvBolt12_protocolId_key" ON "WalletRecvBolt12"("protocolId");
-- AddForeignKey
ALTER TABLE "WalletRecvBolt12" ADD CONSTRAINT "WalletRecvBolt12_protocolId_fkey" FOREIGN KEY ("protocolId") REFERENCES "WalletProtocol"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- vvv Add trigger below manually vvv
CREATE TRIGGER wallet_to_jsonb
    AFTER INSERT OR UPDATE ON "WalletRecvBolt12"
    FOR EACH ROW
    EXECUTE PROCEDURE wallet_to_jsonb();
-- if protocol is for sending you also need to add the wallet_clear_vault trigger:
-- CREATE TRIGGER wallet_clear_vault
--    AFTER DELETE ON "WalletSendClinkDebit"
--    FOR EACH ROW
--    EXECUTE PROCEDURE wallet_clear_vault();
3. Add protocol lib file
- add file to wallets/lib/protocols (see JSDoc for details)
 - import in index.js file and add to default export
 
Example
// wallets/lib/protocols/bolt12.js
export default [
  {
    // same as enum value we added
    name: 'BOLT12',
    displayName: 'BOLT12',
    send: false,
    fields: [
      {
        name: 'offer',
        type: 'text',
        label: 'offer',
        placeholder: 'lno...',
        validate: offerValidator,
        required: true,
      }
    ],
    relationName: 'walletRecvBolt12'
  }
]
diff --git a/wallets/lib/protocols/index.js b/wallets/lib/protocols/index.js
index 8caa5f52..58f5ab86 100644
--- a/wallets/lib/protocols/index.js
+++ b/wallets/lib/protocols/index.js
@@ -7,6 +7,7 @@ import lnbitsSuite from './lnbits'
 import phoenixdSuite from './phoenixd'
 import blinkSuite from './blink'
 import webln from './webln'
+import bolt12 from './bolt12'
 /**
  * Protocol names as used in the database
@@ -44,5 +45,6 @@ export default [
   ...phoenixdSuite,
   ...lnbitsSuite,
   ...blinkSuite,
-  webln
+  webln,
+  bolt12
 ]
4. Add protocol method file
- if protocol to receive payments: Add file to wallets/server/protocols (see JSDoc for details)
 - if protocol to send payments: Add file to wallets/client/protocols (see JSDoc for details)
 - import in index.js file and add to default export
 
Example
// wallets/server/protocols/bolt12.js
// same as enum value we added
export const name = 'BOLT12'
export async function createInvoice ({ msats, description, expiry }, config, { signal }) {
  /* ... code to create invoice using protocol config ... */
}
export async function testCreateInvoice ({ url }, { signal }) {
  return await createInvoice(
    { msats: 1000, description: 'SN test invoice', expiry: 1 },
    { url },
    { signal }
  )
}
diff --git a/wallets/server/protocols/index.js b/wallets/server/protocols/index.js
index 26c292d9..3ac88ae1 100644
--- a/wallets/server/protocols/index.js
+++ b/wallets/server/protocols/index.js
@@ -5,6 +5,7 @@ import * as clnRest from './clnRest'
 import * as phoenixd from './phoenixd'
 import * as blink from './blink'
 import * as lndGrpc from './lndGrpc'
+import * as bolt12 from './bolt12'
 export * from './util'
@@ -56,5 +57,6 @@ export default [
   clnRest,
   phoenixd,
   blink,
-  lndGrpc
+  lndGrpc,
+  bolt12
 ]
5. Update GraphQL code
- add GraphQL type
 - add GraphQL type to 
WalletProtocolConfigunion - add GraphQL type to 
WalletProtocolFieldsfragment via spread operator (...) - add GraphQL mutation to upsert protocol
 - resolve GraphQL type in 
mapWalletResolveTypesfunction 
Example
diff --git a/api/typeDefs/wallet.js b/api/typeDefs/wallet.js
index 3c1fffd1..af3858a5 100644
--- a/api/typeDefs/wallet.js
+++ b/api/typeDefs/wallet.js
@@ -38,6 +38,7 @@ const typeDefs = gql`
     upsertWalletRecvLNDGRPC(walletId: ID, templateId: ID, enabled: Boolean!, networkTests: Boolean, socket: String!, macaroon: String!, cert: String): WalletRecvLNDGRPC!
     upsertWalletSendLNC(walletId: ID, templateId: ID, enabled: Boolean!, pairingPhrase: VaultEntryInput!, localKey: VaultEntryInput!, remoteKey: VaultEntryInput!, serverHost: VaultEntryInput!): WalletSendLNC!
     upsertWalletSendWebLN(walletId: ID, templateId: ID, enabled: Boolean!): WalletSendWebLN!
+    upsertWalletRecvBolt12(walletId: ID, templateId: ID, enabled: Boolean!, networkTests: Boolean, offer: String!): WalletRecvBolt12!
     removeWalletProtocol(id: ID!): Boolean
     updateWalletEncryption(keyHash: String!, wallets: [WalletEncryptionUpdate!]!): Boolean
     updateKeyHash(keyHash: String!): Boolean
@@ -111,6 +112,7 @@ const typeDefs = gql`
     | WalletRecvLightningAddress
     | WalletRecvCLNRest
     | WalletRecvLNDGRPC
+    | WalletRecvBolt12
   type WalletSettings {
     receiveCreditsBelowSats: Int!
@@ -207,6 +209,11 @@ const typeDefs = gql`
     cert: String
   }
+  type WalletRecvBolt12 {
+    id: ID!
+    offer: String!
+  }
+
   input AutowithdrawSettings {
     autoWithdrawThreshold: Int!
     autoWithdrawMaxFeePercent: Float!
diff --git a/wallets/client/fragments/protocol.js b/wallets/client/fragments/protocol.js
index d1a65ff4..138d1a62 100644
--- a/wallets/client/fragments/protocol.js
+++ b/wallets/client/fragments/protocol.js
@@ -109,3 +109,11 @@ export const UPSERT_WALLET_SEND_WEBLN = gql`
     }
   }
 `
+
+export const UPSERT_WALLET_RECEIVE_BOLT12 = gql`
+  mutation upsertWalletRecvBolt12($walletId: ID, $templateId: ID, $enabled: Boolean!, $networkTests: Boolean, $offer: String!) {
+    upsertWalletRecvBolt12(walletId: $walletId, templateId: $templateId, enabled: $enabled, networkTests: $networkTests, offer: $offer) {
+      id
+    }
+  }
+`
diff --git a/wallets/client/fragments/wallet.js b/wallets/client/fragments/wallet.js
index c301f5c1..73d59e6d 100644
--- a/wallets/client/fragments/wallet.js
+++ b/wallets/client/fragments/wallet.js
@@ -106,6 +106,10 @@ const WALLET_PROTOCOL_FIELDS = gql`
         macaroon
         cert
       }
+      ... on WalletRecvBolt12 {
+        id
+        offer
+      }
     }
   }
 `
diff --git a/wallets/server/resolvers/util.js b/wallets/server/resolvers/util.js
index 0155a422..ced4b399 100644
--- a/wallets/server/resolvers/util.js
+++ b/wallets/server/resolvers/util.js
@@ -19,6 +19,8 @@ export function mapWalletResolveTypes (wallet) {
         return 'WalletRecvCLNRest'
       case 'LND_GRPC':
         return 'WalletRecvLNDGRPC'
+      case 'BOLT12':
+        return 'WalletRecvBolt12'
       default:
         return null
     }