diff --git a/.github/workflows/webgl-package.yml b/.github/workflows/webgl-package.yml new file mode 100644 index 0000000..670217c --- /dev/null +++ b/.github/workflows/webgl-package.yml @@ -0,0 +1,18 @@ +name: WebGL package +on: + pull_request: + paths: ['WebGL~/**', '.github/workflows/webgl-package.yml'] + push: + branches: [main] + paths: ['WebGL~/**', '.github/workflows/webgl-package.yml'] +permissions: + contents: read +jobs: + distribution: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + - run: node --test 'WebGL~/Tools/install.test.mjs' diff --git a/CHANGELOG.md b/CHANGELOG.md index e39f3be..2949120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## WebGL preview — 2026-09-16 + +- Publish the current complete Pera/Lute and optional TxnLab/MetaMask Embedded + Wallets package under `WebGL~`, with configurable in-game presentation and + verified C# session acknowledgment. Runtime members remain identical to the + canonical September integration; this is a reusable distribution update. +- Add a dependency-free, offline installer that verifies hashes, preserves + Unity metadata, binds game receipts and refuses unreviewed replacements. +- Add an email/shared-identity setup guide, fullscreen sample and explicit + validation limits. Native exports remain outside this package. +- Preserve the legacy v1 root UPM package, archive its documentation and pin its + installer to v1.2.0. Existing legacy pull requests are unchanged. + ## [1.2.0] - 2026-07-10 ### Added diff --git a/Installer~/BlockmakerInstaller.cs b/Installer~/BlockmakerInstaller.cs index 3d1ebe6..1a934a0 100644 --- a/Installer~/BlockmakerInstaller.cs +++ b/Installer~/BlockmakerInstaller.cs @@ -5,7 +5,7 @@ /// /// Drop this file into your Unity project's Assets folder. -/// It will install the Blockmaker SDK and its dependencies automatically. +/// Legacy v1.2.0 installer. New WebGL games should use WebGL~/README.md. /// You can delete this file after installation. /// [InitializeOnLoad] @@ -79,7 +79,7 @@ static void Install(string manifestPath) var braceIdx = content.IndexOf('{', depsIdx); if (braceIdx >= 0) { - var insert = "\n \"com.blockmaker.sdk\": \"https://github.com/blockmaker-ai/blockmaker-unity.git\",\n \"com.nethereum.unity\": \"4.19.2\",\n \"com.reown.sign.nethereum\": \"1.6.0\",\n \"com.reown.sign.unity\": \"1.6.0\","; + var insert = "\n \"com.blockmaker.sdk\": \"https://github.com/blockmaker-ai/blockmaker-unity.git#v1.2.0\",\n \"com.nethereum.unity\": \"4.19.2\",\n \"com.reown.sign.nethereum\": \"1.6.0\",\n \"com.reown.sign.unity\": \"1.6.0\","; content = content.Substring(0, braceIdx + 1) + insert + content.Substring(braceIdx + 1); } } diff --git a/LEGACY_V1.md b/LEGACY_V1.md new file mode 100644 index 0000000..4acd1dc --- /dev/null +++ b/LEGACY_V1.md @@ -0,0 +1,304 @@ +# Legacy v1 documentation + +This is the historical v1.2.0 guide. Its server OTP/Magic and native-platform +claims do not describe the current WebGL package. Do not use these email +paths for new integrations. Start with the [current SDK guide](README.md). +Existing projects can pin v1.2.0 while planning an explicit migration. + +# Blockmaker Unity SDK + +Add Algorand wallet auth and transaction signing to your Unity game. Open-source, free, built for Unity 6+. + +## Supported Wallets + +| Wallet | How it works | +|--------|-------------| +| **Pera** | QR code scan (WalletConnect v1). On WebGL the SDK uses Pera's official [@perawallet/connect](https://github.com/perawallet/connect); mobile browsers get an "Open in wallet app" deep link | +| **Defly** | QR code scan (WalletConnect v2), mobile deep link per Defly's official SDK | +| **X-Chain** *(beta)* | Any EVM wallet via [xChain Accounts](https://github.com/algorandfoundation/xchain-accounts). On WebGL the SDK discovers every wallet installed in the player's browser (EIP-6963) and shows it in the picker with its real icon — MetaMask, Rainbow, Coinbase Wallet, Trust + more; native builds connect via WalletConnect QR. Off by default — set `enableEvmXChain` in your BlockmakerConfig | +| **Email** | Server-managed OTP out of the box (all platforms); optionally Magic SDK on WebGL with your own key | + +> Currently Algorand **mainnet** only. + +## Installation + +### One-click install + +1. **[Download BlockmakerInstaller.cs](https://raw.githubusercontent.com/blockmaker-ai/blockmaker-unity/main/Installer~/BlockmakerInstaller.cs)** (right-click → Save As) +2. Drag it into your Unity project (anywhere in the Assets folder) +3. A dialog will appear — click **Install** +4. Unity installs everything automatically. Done. + +You can delete the installer file after installation. + +
+Manual install (if you prefer) + +Open `Packages/manifest.json` in your project folder and add: + +**In `"dependencies"`:** +```json +"com.blockmaker.sdk": "https://github.com/blockmaker-ai/blockmaker-unity.git#v1.2.0", +"com.nethereum.unity": "4.19.2", +"com.reown.sign.nethereum": "1.6.0", +"com.reown.sign.unity": "1.6.0", +``` + +**At the bottom of the file, before the last `}`:** +```json +, +"scopedRegistries": [ + { + "name": "OpenUPM", + "url": "https://package.openupm.com", + "scopes": ["com.reown", "com.nethereum", "com.cysharp"] + } +] +``` + +Save and reopen Unity. + +
+ +## Setup + +Go to **Blockmaker > Setup Scene** in the menu bar. This automatically: + +- Creates a BlockmakerConfig asset +- Adds BlockmakerAuth with the config wired up +- Adds the auth UI with all UXML assets pre-assigned +- Creates PanelSettings if needed +- Adds a Connect Wallet button + +Hit Play — the wallet system is ready. No API keys or signups needed. + +### Sample scene + +Want to see it working first? In **Package Manager > Blockmaker SDK > Samples**, import the **Wallet Demo**. Add the `WalletDemo` script to an empty GameObject and hit Play — includes wallet connection and transaction signing. + +## Usage + +### Connect a wallet + +```csharp +using Blockmaker; + +// Pera (QR code) +BlockmakerAuth.Instance.ConnectWallet("Pera", + identity => Debug.Log($"Connected: {identity.Address}"), + error => Debug.Log(error) +); + +// Defly (QR code) +BlockmakerAuth.Instance.ConnectWallet("Defly", + identity => Debug.Log($"Connected: {identity.Address}"), + error => Debug.Log(error) +); + +// X-Chain — any EVM wallet (beta). On WebGL this auto-picks the player's +// last-used browser wallet; native builds show a WalletConnect QR. +// Off by default — set enableEvmXChain in your BlockmakerConfig. +BlockmakerAuth.Instance.ConnectEvm( + identity => Debug.Log($"Connected: {identity.Address}"), // Algorand address, derived from the EVM key + error => Debug.Log(error) +); + +// Email login — built-in server OTP (works everywhere, no keys needed) +BlockmakerAuth.Instance.RequestEmailOTP("player@example.com", + () => Debug.Log("Code sent — check your inbox"), + error => Debug.Log(error) +); +BlockmakerAuth.Instance.VerifyEmailOTP("player@example.com", "123456", + identity => Debug.Log($"Signed in: {identity.Address}"), + error => Debug.Log(error) +); + +// Email login via Magic SDK — WebGL only, requires magicPublishableKey in your config +// (without a key the built-in auth UI automatically uses the OTP flow above) +BlockmakerAuth.Instance.ConnectMagicEmail("player@example.com", + identity => Debug.Log($"Signed in: {identity.Address}"), + error => Debug.Log(error) +); +``` + +### Async/await + +```csharp +var identity = await BlockmakerAuth.Instance.ConnectWalletAsync("Pera"); +var evmIdentity = await BlockmakerAuth.Instance.ConnectEvmAsync(); +``` + +### Sign transactions + +```csharp +var identity = BlockmakerAuth.Instance.Identity; + +// Single transaction +yield return identity.SignTransaction(unsignedTxnBase64, + signed => Debug.Log("Signed!"), + error => Debug.Log(error) +); + +// Atomic group +yield return identity.SignTransactions(unsignedTxnsBase64, + signed => Debug.Log($"Signed {signed.Length} transactions"), + error => Debug.Log(error) +); +``` + +### Check state + +```csharp +BlockmakerAuth.Instance.HasWallet // true if a wallet is connected +BlockmakerAuth.Instance.Address // Algorand address +BlockmakerAuth.Instance.CanSign // true if the wallet can sign right now +BlockmakerAuth.Instance.IsLoggedIn // true for Email or SelfCustody tier +BlockmakerAuth.Instance.Tier // Guest, Email, or SelfCustody +``` + +### Listen for changes + +```csharp +void OnEnable() +{ + BlockmakerAuth.OnIdentityChanged += HandleIdentityChanged; +} + +void OnDisable() +{ + BlockmakerAuth.OnIdentityChanged -= HandleIdentityChanged; +} + +void HandleIdentityChanged(IBlockmakerIdentity identity) +{ + Debug.Log($"Identity changed: {identity.ProviderName} — {identity.Address}"); +} +``` + +### Session restore & sign-in status + +Self-custody sign-in is **two approvals**: connect, then a signature that logs the +player into the backend. The SDK exposes everything a custom UI needs to render that +honestly: + +```csharp +// Boot-time restore: don't guess — wait for the restore to settle. +if (BlockmakerAuth.SessionRestoreSettled) { /* auth state is known */ } +BlockmakerAuth.OnSessionRestoreSettled += () => + Debug.Log($"Restore settled — tier: {BlockmakerAuth.Instance.Tier}"); + +// Progress messages while the player must act in their wallet app. +BlockmakerAuth.OnAuthStatus += msg => statusLabel.text = msg; + +// The step-2 (login signature) window: offer RESEND / CANCEL instead of a dead end. +if (BlockmakerAuth.CanRetryWalletLogin) +{ + BlockmakerAuth.Instance.RetryWalletLogin(); // push a fresh sign-in request + // or: BlockmakerAuth.Instance.CancelWalletLogin(); +} + +// Skip best-effort backend calls that would 401 for guests. +if (BlockmakerClient.Instance.HasBackendSession) { /* safe to call player APIs */ } +``` + +The built-in auth UI already implements all of this (a "STEP 2 OF 2" panel with +RESEND / CANCEL). + +### WebGL: self-hosting the wallet JS (optional) + +On WebGL the SDK loads its wallet libraries from jsDelivr at runtime — zero setup. +For immunity to ad-blockers and CDN outages you can ship the bundles with your game: +build IIFE bundles that assign `window.BmPeraVendor = { PeraWalletConnect, algosdk }` +and/or `window.BmWCVendor = { SignClient, QRCode }`, and load them via `