Show-me-wallet 運作原理

Proof of wallet (自證wallet QR code)

證明wallet的部份,app裡做了幾件事:

(1) connect Phantom wallet, 得知用戶的wallet address (後稱為<wallet address>)。


(2) 在app裡生成一對本地儲存的keypair作為grant key。
(keypair及public key後稱為<grant keypair>及<grant public key>)。


(3) 草擬一段援權聲明 (後稱為<grant payload message>):

v0: Approve 'Show-me-wallet' grant key '<grant public key>' for scope 'nftOwnerProof' between time '<grant nbf>' and '<grant exp>'.

這裡<grant nbf>與<grant exp>都是一個ISO8601格式時間, 意思就是一般auth token應用的not-before及expire。簡單來說就是只能在這兩個時間之間的時間段內生效。

目前這裡我是設定了1小時授權時間。

實際的message大概會是這樣:

我們會提交到Phantom Wallet要求做off-chain簽名。(Ed25519簽名及base58 encode)


(4) 至此app裡所持有的數據:

  • 用戶wallet address (<wallet address>)

  • app內本地grant key keypair (<grant keypair>)

  • 授權聲明 (<grant payload message>)

  • 授權聲明簽名 (<grant payload message signature>)

雖然現在已經擁有授權作proof of wallet, 但我們不會只用這些授權來直接使用。因為一小時授權很長, 如果被人偷去這份聲明, 就能在一小時內扮演其他人。

所以流程上, 我們要求有二次授權去證明其繼續持有有效證明。


(5) 我們會要求用<grant keypair>, 每10秒為周期生成短期的二次授權。

二次授權message (後稱為<grant proof message>)如下:

iss=<grant proof issue time>;nbfs=5;exps=10

這裡的幾個attribute意思:

  • iss, 就是"二次授權"生成時間。

  • nbfs與exps, 也就是"二次授權"允許的not-before秒數及epxire秒數。

  • 整體意思就是說, 這是在iss的timestamp時生成, 而使用時不能早於iss前5秒, 而且也會在iss後10秒失效。

我們app裡會用<grant keypair>去sign這二次授權message, 得到<grant proof message signature>。
這裡也是用Ed25519簽名及base58 encode的格式。
由於這是用本地keypair sign也就不用再經phantom wallet了。


(6) 如何把這些東西呈現呢? 我們把它們塞進json用QR code顯示出來。

json payload格式如下(實際上是compacted):

{
    "owner": <wallet address>,
    "ownerGrantMsg": <grant payload message (packed)>,
    "ownerGrantMsgSign": <grant payload message signature>,
    "grantProofMsg": <grant proof message>,
    "grantProofMsgSign": <grant proof message signature>,
}

留意下, ownerGrantMsg我們不是用原本那臭長的sign message string, 而是用compacted string格式以節省payload長度。

compacted string格式如下:

v=0;app=Show-me-wallet;gk=<grant public key>;scp=nftOwnerProof;nbf=<grant nbf>;exp=<grant exp>

整體還是臭長的, 不過算了XD
我們就用這去生成QR code了。


驗證wallet QR code

驗證的流程如下:

(1) 當然是Scan QR code, 提取前面生成QR code的那些內容。


(2) 從Payload裡, 先提取用戶wallet address。
然後將"ownerGrantMsg部份重新構成grant payload message, 及驗證其signature。

再由grant payload message中提取獲授權的grant key。再與"grantProofMsg"及signature做驗證。

以上除了signature驗證, 也會加上NBF及expire時間的各驗證。

{
    "owner": <wallet address>,
    "ownerGrantMsg": <grant payload message (packed)>,
    "ownerGrantMsgSign": <grant payload message signature>,
    "grantProofMsg": <grant proof message>,
    "grantProofMsgSign": <grant proof message signature>,
}

以上做了那麼多, 其實就只是為了驗證用戶的wallet address身份。


(3) 得知身份後, 就用Helius的API查看用戶wallet address有什麼NFT。

然後就是在畫面上把NFT的資料及圖片顯示出來。


相關文章

Did you find this article valuable?

Support eric.dev.blog by becoming a sponsor. Any amount is appreciated!