Skip to content

Commit

Permalink
Merge pull request #1735 from aeternity/feature/fix-examples
Browse files Browse the repository at this point in the history
Fix BrowserRuntime in Firefox and pre-release fixes
  • Loading branch information
davidyuk committed Jan 13, 2023
2 parents 8239fa0 + 47243a0 commit 77ae7a6
Show file tree
Hide file tree
Showing 35 changed files with 339 additions and 192 deletions.
2 changes: 1 addition & 1 deletion docker/accounts_test.json
@@ -1,3 +1,3 @@
{
"ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR": 100000000000000000000000000000000000000000
"ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E": 100000000000000000000000000000000000000000
}
2 changes: 1 addition & 1 deletion docs/guides/aens.md
Expand Up @@ -311,7 +311,7 @@ console.log(nameTransferTx)
fee: 17300000000000,
nameId: 'nm_1Cz5HGY8PMWZxNrM6s51CtsJZDU3DDT1LdmpEipa3DRghyGz5',
nonce: 33,
recipientId: 'ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR',
recipientId: 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E',
type: 'NameTransferTx',
version: 1
},
Expand Down
8 changes: 5 additions & 3 deletions examples/browser/aepp/src/Basic.vue
Expand Up @@ -57,6 +57,7 @@

<script>
import { mapState, mapGetters } from 'vuex';
import { encode, Encoding } from '@aeternity/aepp-sdk';
import Value from './Value.vue';
export default {
Expand All @@ -80,8 +81,7 @@ export default {
({ aeSdk, address, networkId }) => [aeSdk, address, networkId],
([aeSdk, address]) => {
if (!aeSdk) return;
this.compilerVersionPromise = aeSdk.compilerApi.apiVersion()
.then(({ apiVersion }) => apiVersion);
this.compilerVersionPromise = aeSdk.compilerApi.version();
this.balancePromise = aeSdk.getBalance(address);
this.heightPromise = aeSdk.getHeight();
this.nodeInfoPromise = aeSdk.getNodeInfo();
Expand All @@ -91,7 +91,9 @@ export default {
},
methods: {
spend() {
return this.aeSdk.spend(this.spendAmount, this.spendTo, { payload: this.spendPayload });
return this.aeSdk.spend(this.spendAmount, this.spendTo, {
payload: encode(new TextEncoder().encode(this.spendPayload), Encoding.Bytearray),
});
},
},
};
Expand Down
55 changes: 35 additions & 20 deletions examples/browser/aepp/src/Connect.vue
Expand Up @@ -15,7 +15,8 @@
</div>
<button
v-if="connectMethod && !walletConnected"
@click="connectPromise = connect().then(() => 'Ready')"
:disabled="walletConnecting"
@click="connect"
>
Connect
</button>
Expand All @@ -30,7 +31,13 @@
<div class="group">
<div>
<div>SDK status</div>
<Value :value="connectPromise" />
<div>
{{
(walletConnected && 'Wallet connected')
|| (walletConnecting && 'Wallet connecting')
|| 'Ready to connect to wallet'
}}
</div>
</div>
<div>
<div>Wallet name</div>
Expand All @@ -40,16 +47,16 @@
</template>

<script>
import { walletDetector, BrowserWindowMessageConnection } from '@aeternity/aepp-sdk';
import {
walletDetector, BrowserWindowMessageConnection, RpcConnectionDenyError,
} from '@aeternity/aepp-sdk';
import { mapGetters } from 'vuex';
import Value from './Value.vue';
export default {
components: { Value },
data: () => ({
connectMethod: 'default',
walletConnected: false,
connectPromise: null,
walletConnecting: null,
reverseIframe: null,
reverseIframeWalletUrl: 'http://localhost:9000',
walletInfo: null,
Expand All @@ -70,14 +77,8 @@ export default {
const handleWallets = async ({ wallets, newWallet }) => {
newWallet = newWallet || Object.values(wallets)[0];
if (confirm(`Do you want to connect to wallet ${newWallet.info.name} with id ${newWallet.info.id}`)) {
console.log('newWallet', newWallet);
stopScan();
this.walletInfo = await this.aeSdk.connectToWallet(newWallet.getConnection());
this.walletConnected = true;
const { address: { current } } = await this.aeSdk.subscribeAddress('subscribe', 'connected');
this.$store.commit('aeSdk/setAddress', Object.keys(current)[0]);
resolve();
resolve(newWallet.getConnection());
}
};
Expand All @@ -86,14 +87,28 @@ export default {
});
},
async connect() {
if (this.connectMethod === 'reverse-iframe') {
this.reverseIframe = document.createElement('iframe');
this.reverseIframe.src = this.reverseIframeWalletUrl;
this.reverseIframe.style.display = 'none';
document.body.appendChild(this.reverseIframe);
this.walletConnecting = true;
try {
if (this.connectMethod === 'reverse-iframe') {
this.reverseIframe = document.createElement('iframe');
this.reverseIframe.src = this.reverseIframeWalletUrl;
this.reverseIframe.style.display = 'none';
document.body.appendChild(this.reverseIframe);
}
await this.$store.dispatch('aeSdk/initialize');
const connection = await this.scanForWallets();
try {
this.walletInfo = await this.aeSdk.connectToWallet(connection);
} catch (error) {
if (error instanceof RpcConnectionDenyError) connection.disconnect();
throw error;
}
this.walletConnected = true;
const { address: { current } } = await this.aeSdk.subscribeAddress('subscribe', 'connected');
this.$store.commit('aeSdk/setAddress', Object.keys(current)[0]);
} finally {
this.walletConnecting = false;
}
await this.$store.dispatch('aeSdk/initialize');
await this.scanForWallets();
},
async disconnect() {
await this.aeSdk.disconnectWallet();
Expand Down
10 changes: 1 addition & 9 deletions examples/browser/aepp/src/styles.scss
Expand Up @@ -26,16 +26,8 @@ button {
}
}

h1, h2 {
@extend .mt-2, .font-bold;
}

h1 {
@extend .text-3xl;
}

h2 {
@extend .text-2xl;
@extend .mt-2, .font-bold, .text-2xl;
}

input:not([type=radio]), textarea {
Expand Down
2 changes: 1 addition & 1 deletion examples/browser/wallet-iframe/src/App.vue
Expand Up @@ -115,7 +115,7 @@ export default {
{ name: 'ae_mainnet', instance: new Node('https://mainnet.aeternity.io') },
],
accounts: [
new AccountMemoryProtected('bf66e1c256931870908a649572ed0257876bb84e3cdf71efb12f56c7335fad54d5cf08400e988222f26eb4b02c8f89077457467211a6e6d955edb70749c6a33b'),
new AccountMemoryProtected('9ebd7beda0c79af72a42ece3821a56eff16359b6df376cf049aee995565f022f840c974b97164776454ba119d84edc4d6058a8dec92b6edc578ab2d30b4c4200'),
AccountMemoryProtected.generate(),
],
onCompiler: new CompilerHttp('https://v7.compiler.aepps.com'),
Expand Down
10 changes: 1 addition & 9 deletions examples/browser/wallet-iframe/src/styles.scss
Expand Up @@ -22,16 +22,8 @@ button {
}
}

h1, h2 {
@extend .mt-2, .font-bold;
}

h1 {
@extend .text-3xl;
}

h2 {
@extend .text-2xl;
@extend .mt-2, .font-bold, .text-2xl;
}

.group {
Expand Down
1 change: 1 addition & 0 deletions examples/browser/wallet-web-extension/package.json
Expand Up @@ -9,6 +9,7 @@
"dependencies": {
"@aeternity/aepp-sdk": "file:../../..",
"core-js": "^3.22.6",
"tailwindcss": "^2.2.19",
"vue": "^2.6.14",
"webextension-polyfill": "^0.9.0"
},
Expand Down
62 changes: 54 additions & 8 deletions examples/browser/wallet-web-extension/src/Popup.vue
@@ -1,13 +1,59 @@
<template>
<div>
<h3>Wallet WebExtension</h3>
<img src="../public/icons/128.png" alt="Logo">
<div class="popup">
<template v-if="popupParameters">
<h2>Aepp at {{ aeppOrigin }} want to {{ action }}</h2>
<div class="group">
<div>
<div>Request details</div>
<div>{{ JSON.stringify(popupParameters, null, 2) }}</div>
</div>

<button @click="() => respond(true)">
Confirm
</button>
<button @click="() => respond(false)">
Reject
</button>
</div>
</template>

<h2 v-else>Wallet WebExtension</h2>
</div>
</template>

<style>
html {
width: 400px;
height: 400px;
<script>
import browser from 'webextension-polyfill';
import { unpackTx } from '@aeternity/aepp-sdk';
export default {
data: () => ({
aeppOrigin: null,
action: null,
popupId: null,
popupParameters: null,
isResponded: false,
}),
mounted() {
const data = new URL(location).searchParams.get('data');
if (data != null) {
const { aeppOrigin, action, popupId, ...params } = JSON.parse(data);
if (params.transaction) params.unpackedTx = unpackTx(params.transaction);
this.aeppOrigin = aeppOrigin;
this.action = action;
this.popupId = popupId;
this.popupParameters = params;
window.addEventListener('beforeunload', () => this.respond(false));
}
},
methods: {
async respond(response) {
if (this.isResponded) return;
await browser.runtime.sendMessage({ response, popupId: this.popupId });
this.isResponded = true;
window.close();
},
},
}
</style>
</script>

<style lang="scss" src="./styles.scss" />
68 changes: 49 additions & 19 deletions examples/browser/wallet-web-extension/src/background.js
Expand Up @@ -4,27 +4,52 @@ import {
WALLET_TYPE, RpcConnectionDenyError, RpcRejectedByUserError,
} from '@aeternity/aepp-sdk';

let popupCounter = 0;
async function confirmInPopup(parameters) {
const popupUrl = new URL(browser.runtime.getURL('./popup.html'));
const popupId = popupCounter;
popupCounter += 1;
popupUrl.searchParams.set('data', JSON.stringify({ ...parameters, popupId }));
await browser.windows.create({
url: popupUrl.toString(),
type: 'popup',
height: 600,
width: 600,
});
return new Promise((resolve) => {
const handler = (message, sender, sendResponse) => {
if (message.popupId !== popupId) return;
resolve(message.response);
sendResponse();
browser.runtime.onMessage.removeListener(handler);
};
browser.runtime.onMessage.addListener(handler);
});
}

const aeppInfo = {};
const genConfirmCallback = (actionName) => (aeppId, parameters, origin) => {
if (!confirm([
`Client ${aeppInfo[aeppId].name} with id ${aeppId} at ${origin} want to ${actionName}`,
JSON.stringify(parameters, null, 2),
].join('\n'))) {
throw new RpcRejectedByUserError();
}
const genConfirmCallback = (action) => async (aeppId, parameters, aeppOrigin) => {
const isConfirmed = await confirmInPopup({
...parameters,
action,
aeppId,
aeppInfo: aeppInfo[aeppId],
aeppOrigin,
});
if (!isConfirmed) throw new RpcRejectedByUserError();
};

class AccountMemoryProtected extends MemoryAccount {
async signTransaction(tx, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
async signTransaction(transaction, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
if (id != null) {
genConfirmCallback(`sign transaction ${tx}`)(id, options, aeppOrigin);
await genConfirmCallback('sign transaction')(id, { ...options, transaction }, aeppOrigin);
}
return super.signTransaction(tx, options);
return super.signTransaction(transaction, options);
}

async signMessage(message, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
if (id != null) {
genConfirmCallback(`sign message ${message}`)(id, options, aeppOrigin);
await genConfirmCallback('sign message')(id, { ...options, message }, aeppOrigin);
}
return super.signMessage(message, options);
}
Expand All @@ -42,20 +67,24 @@ const aeSdk = new AeSdkWallet({
instance: new Node('https://testnet.aeternity.io'),
}],
accounts: [
new AccountMemoryProtected('bf66e1c256931870908a649572ed0257876bb84e3cdf71efb12f56c7335fad54d5cf08400e988222f26eb4b02c8f89077457467211a6e6d955edb70749c6a33b'),
new AccountMemoryProtected('9ebd7beda0c79af72a42ece3821a56eff16359b6df376cf049aee995565f022f840c974b97164776454ba119d84edc4d6058a8dec92b6edc578ab2d30b4c4200'),
AccountMemoryProtected.generate(),
],
id: browser.runtime.id,
type: WALLET_TYPE.extension,
name: 'Wallet WebExtension',
onConnection: (aeppId, params, origin) => {
if (!confirm(`Client ${params.name} with id ${aeppId} at ${origin} want to connect`)) {
throw new RpcConnectionDenyError();
}
async onConnection(aeppId, params, aeppOrigin) {
const isConfirmed = await confirmInPopup({
action: 'connect',
aeppId,
aeppInfo: params,
aeppOrigin,
});
if (!isConfirmed) throw new RpcConnectionDenyError();
aeppInfo[aeppId] = params;
},
onDisconnect(msg, client) {
console.log('Client disconnected:', client);
onDisconnect(aeppId, payload) {
console.log('Client disconnected:', aeppId, payload);
},
onSubscription: genConfirmCallback('subscription'),
onAskAccounts: genConfirmCallback('get accounts'),
Expand All @@ -70,7 +99,8 @@ browser.runtime.onConnect.addListener((port) => {
const clientId = aeSdk.addRpcClient(connection);
// share wallet details
aeSdk.shareWalletInfo(clientId);
setInterval(() => aeSdk.shareWalletInfo(clientId), 3000);
const interval = setInterval(() => aeSdk.shareWalletInfo(clientId), 3000);
port.onDisconnect.addListener(() => clearInterval(interval));
});

console.log('Wallet initialized!');

0 comments on commit 77ae7a6

Please sign in to comment.