Proxy Wallets

To open up Lambda Protocol to a bigger userbase we developed so called Proxy Wallets. Wallets that don't have to be Bitcoin wallets. It is important to differentiate them from non custodial wallets. They are still yours and you fully control them.

Any address that is able to sign a message can be used as proxy wallets. At the moment we support Bitcoin Taproot and Ethereum addresses.

How do they work

Let's start from the before version and move towards the proxy wallets and how they are created. For this example we use a LMDA transfer inscription to a random wallet.

{
    "p": "lam",
    "op": "call",
    "contract": "LMDA",
    "function": "transfer",
    "args": [
        "bc1q4rjnwns2rqsjp7y6af65jfk6kkr3tvzckplttm",
        100000000000
    ]
}

Before

Before proxy wallets every user had to do two steps to verify the intention.

  1. Mint it to any wallet

  2. Send the inscription to the same wallet

This made sure if somebody minted a malicious inscription to your wallet nothing would happen.

However, this made the UX worse than it should be and didn't allow for any non Bitcoin addresses.

After

With proxy wallets there is only one step necessary

  1. Mint it from any wallet

As soon as the inscription is confirmed, it gets executed, no matter who received or minted it. To achieve this we have to do some clever signature stuff.

Signatures

Any address is capable of creating a signature of a message. This signature can be verified later to match the address. This makes it is impossible to forge signatures. If you control the wallet, only you can create signatures that are verifiable by your address.

So to make this work, we take the prior inscription, add a nonce to it and sign it.

{
    "p": "lam",
    "op": "call",
    "contract": "LMDA",
    "function": "transfer",
    "args": [
        "bc1q4rjnwns2rqsjp7y6af65jfk6kkr3tvzckplttm",
        100000000000
    ],
    "n": 0
}

signing this creates a signature that looks different based on the type of address.

Then, we add a whole sig property to our JSON.

{
    "p": "lam",
    "op": "call",
    "contract": "LMDA",
    "function": "transfer",
    "args": [
        "bc1q4rjnwns2rqsjp7y6af65jfk6kkr3tvzckplttm",
        100000000000
    ],
    "sig": {
        "p": "btc",
        "a": "bc1pymguvkanjvxzhwj4m3tdsrsvurj9z237vpwh0uyj6hmaxmnccjeqvej3g4",
        "s": "AUDeJUFUw/DK5BY56Vr6DnV4F6/Pe2Kp+EEsoqLSbhaThwrMu0GYQ3ruP+...",
        "n": 0
    }
}

The sig property contains

  • p: to ensure the type of proxy used. Currently btc or eth

  • a: the address used to sign the inscription. The signature is later verified against it.

  • s: the signature itself

  • n: the nonce

As soon as the inscription is confirmed onchain it is executed.

Nonce

As the inscription is public we need to ensure duplicating it doesn't execute it again. Therefore, we use a nonce a simple integer that goes up by one everytime an inscription with a signature is confirmed and verified. To get the last nonce you can use our API.

For Ethereum

The logic above can be used for any private public key pair as long as the verification logic is written in the indexer.

Ethereum is already supported. As soon as an inscription with a sig property is confirmed onchain it is executed. This allows you to hold and use DeFi on Lambda Protocol from your Ethereum address, without giving up control or knowing about BTC or Ordinals.

At the moment you have to inscribe the full inscription yourself, so you still need a Bitcoin wallet. But in the future we develop a service that does it for a small fee, paid directly on Lambda Protocol using Multi Inscriptions.

Last updated