Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 145 additions & 18 deletions examples/web-simple/index.html
Original file line number Diff line number Diff line change
@@ -1,23 +1,150 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Concordium SDK - Web UMD Test</title>
<script src="../../node_modules/@concordium/web-sdk/lib/min/concordium.web.min.js"></script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 0 20px;
line-height: 1.6;
}
h1 {
border-bottom: 2px solid #eee;
padding-bottom: 10px;
}
.test {
padding: 10px;
margin: 8px 0;
border-radius: 4px;
border-left: 4px solid;
}
.test.pass {
background: #f0fff0;
border-color: #2e7d32;
}
.test.fail {
background: #fff0f0;
border-color: #c62828;
}
.test-name {
font-weight: 600;
}
.test-result {
font-family: monospace;
font-size: 12px;
color: #666;
margin-top: 4px;
word-break: break-all;
}
.status {
font-weight: bold;
}
.status.pass {
color: #2e7d32;
}
.status.fail {
color: #c62828;
}
#summary {
margin-top: 20px;
padding: 15px;
background: #f5f5f5;
border-radius: 4px;
font-weight: 600;
}
</style>
</head>

<head>
<meta charset="utf-8" />
<script src="../../node_modules/@concordium/web-sdk/lib/min/concordium.web.min.js"></script>
</head>

<body>
<div id="root"></div>
<script>
// Verifies that PLT works in UMD.
const account = concordiumSDK.AccountAddress.fromBase58('4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd');
const tokenAmount = concordiumSDK.TokenAmount.create(100, 2);
console.log(account, tokenAmount);

// Verifies that UMD wasm functions work
const schema = concordiumSDK.toBuffer('FAACAAAABAAAAGtleXMQAR4gAAAADgAAAGF1eGlsaWFyeV9kYXRhEAEC', 'base64');
console.log(concordiumSDK.displayTypeSchemaTemplate(schema));
</script>
</body>
<body>
<h1>Concordium SDK - Web UMD Test</h1>
<div id="results"></div>
<div id="summary"></div>

<script>
const results = document.getElementById('results');
const summary = document.getElementById('summary');
let passed = 0,
failed = 0;

function test(name, fn) {
const div = document.createElement('div');
div.className = 'test';
try {
const result = fn();
div.className += ' pass';
div.innerHTML = `<span class="status pass">✓ PASS</span> <span class="test-name">${name}</span>`;
if (result !== undefined) {
div.innerHTML += `<div class="test-result">${escapeHtml(String(result))}</div>`;
}
passed++;
} catch (e) {
div.className += ' fail';
div.innerHTML = `<span class="status fail">✗ FAIL</span> <span class="test-name">${name}</span>`;
div.innerHTML += `<div class="test-result">${escapeHtml(e.message)}</div>`;
failed++;
}
results.appendChild(div);
}

function escapeHtml(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

// Test: AccountAddress.fromBase58
test('AccountAddress.fromBase58()', () => {
const account = concordiumSDK.AccountAddress.fromBase58(
'4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'
);
return account.address;
});

// Test: TokenAmount.create (PLT functionality)
test('TokenAmount.create() - PLT functionality', () => {
const tokenAmount = concordiumSDK.TokenAmount.create(100, 2);
return `TokenAmount: ${tokenAmount.toString()}`;
});

// Test: displayTypeSchemaTemplate (WASM functionality)
test('displayTypeSchemaTemplate() - WASM functionality', () => {
const schema = concordiumSDK.toBuffer(
'FAACAAAABAAAAGtleXMQAR4gAAAADgAAAGF1eGlsaWFyeV9kYXRhEAEC',
'base64'
);
const template = concordiumSDK.displayTypeSchemaTemplate(schema);
return template.substring(0, 100) + (template.length > 100 ? '...' : '');
});

// Test: ConcordiumGRPCWebClient exists
test('ConcordiumGRPCWebClient available', () => {
if (typeof concordiumSDK.ConcordiumGRPCWebClient !== 'function') {
throw new Error('ConcordiumGRPCWebClient is not a function');
}
return 'Constructor available';
});

// Test: generateBakerKeys (WASM - wallet module)
test('generateBakerKeys() - WASM wallet module', () => {
const account = concordiumSDK.AccountAddress.fromBase58(
'4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'
);
const keys = concordiumSDK.generateBakerKeys(account);
if (!keys.electionVerifyKey || !keys.signatureVerifyKey || !keys.aggregationVerifyKey) {
throw new Error('Missing expected keys in result');
}
return `electionVerifyKey: ${keys.electionVerifyKey.substring(0, 20)}...`;
});

// Display summary
const total = passed + failed;
summary.innerHTML =
`Tests: ${passed}/${total} passed` +
(failed > 0
? ` <span style="color: #c62828">(${failed} failed)</span>`
: ' <span style="color: #2e7d32">✓</span>');
</script>
</body>
</html>
6 changes: 6 additions & 0 deletions packages/rust-bindings/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

## 4.0.1

### Fixed

- An issue where the browser entrypoints of the package did not work.

## 4.0.0

### Breaking changes
Expand Down
4 changes: 2 additions & 2 deletions packages/rust-bindings/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions packages/rust-bindings/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@concordium/rust-bindings",
"version": "4.0.0",
"version": "4.0.1",
"license": "Apache-2.0",
"type": "module",
"engines": {
Expand Down Expand Up @@ -28,8 +28,9 @@
"default": "./lib/dapp/node/cjs/index.cjs"
},
"browser": {
"module": "./lib/dapp/web/esm/index.min.js",
"types": "./lib/dapp/web/esm/index.d.ts",
"import": "./lib/dapp/web/esm/index.js",
"import": "./lib/dapp/web/esm/index.min.js",
"default": "./lib/dapp/web/umd/index.min.js"
},
"default": "./lib/dapp/web/umd/index.min.js"
Expand All @@ -41,8 +42,9 @@
"default": "./lib/dapp/node/cjs/index.cjs"
},
"browser": {
"module": "./lib/dapp/web/esm/index.min.js",
"types": "./lib/dapp/web/esm/index.d.ts",
"import": "./lib/dapp/web/esm/index.js",
"import": "./lib/dapp/web/esm/index.min.js",
"default": "./lib/dapp/web/umd/index.min.js"
},
"default": "./lib/dapp/web/umd/index.min.js"
Expand All @@ -54,8 +56,9 @@
"default": "./lib/wallet/node/cjs/index.cjs"
},
"browser": {
"module": "./lib/wallet/web/esm/index.min.js",
"types": "./lib/wallet/web/esm/index.d.ts",
"import": "./lib/wallet/web/esm/index.js",
"import": "./lib/wallet/web/esm/index.min.js",
"default": "./lib/wallet/web/umd/index.min.js"
},
"default": "./lib/wallet/web/umd/index.min.js"
Expand All @@ -79,7 +82,7 @@
"scripts": {
"rustfmt": "cargo +nightly-2023-04-01-x86_64-unknown-linux-gnu fmt -- --color=always",
"clippy": "cargo +1.73 clippy --color=always --tests --benches -- -Dclippy::all",
"build-web": "wasm-pack build ./packages/$0 --target web --out-dir $INIT_CWD/lib/$0/web/esm --out-name index",
"build-web": "wasm-pack build ./packages/$0 --target web --out-dir $INIT_CWD/lib/$0/web/esm --out-name index && tsx ./scripts/web-esm-remove-init.ts $0",
"build-node": "wasm-pack build ./packages/$0 --target nodejs --out-dir $INIT_CWD/lib/$0/node/cjs --out-name index && tsx ./scripts/fix-nodejs-ext.ts",
"build-bundler": "wasm-pack build ./packages/$0 --target bundler --out-dir $INIT_CWD/lib/$0/bundler --out-name index",
"build-all": "yarn build-web $0 && yarn build-node $0 && yarn build-bundler $0",
Expand Down
32 changes: 32 additions & 0 deletions packages/rust-bindings/scripts/web-esm-remove-init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as fs from 'fs';
import { fileURLToPath } from 'node:url';
import * as path from 'path';

/**
* The point of this script is to convert the ESM produced by wasm-pack to something that can be compiled by bundlers.
*
* The error happening when _not_ running the script is related to the `new URL('index_bg.wasm', import.meta.url)`, as
* bundlers will try to read the file at the location. The function this code snippet is embedded in, is not used in the
* format exposed by the rust-bindings library.
*/

const name = process.argv[2];
if (!name) {
console.error('Usage: tsx scripts/web-esm-remove-init.ts <name>');
process.exit(1);
}

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const filePath = path.resolve(__dirname, '..', `lib/${name}/web/esm/index.js`);

if (!fs.existsSync(filePath)) {
console.warn(`${filePath} not found.`);
process.exit(0);
}
const content = fs.readFileSync(filePath, 'utf8');
const updated = content.replace("module_or_path = new URL('index_bg.wasm', import.meta.url);", '');
if (updated !== content) {
fs.writeFileSync(filePath, updated);
} else {
console.warn(`No line to remove in ${filePath}`);
}
34 changes: 32 additions & 2 deletions packages/rust-bindings/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type WebpackEnv = Partial<{
package: string;
}>;

function configFor(target: 'web' | 'node', pkg?: string): Configuration {
function configFor(target: 'web' | 'node', output: 'umd' | 'esm', pkg?: string): Configuration {
const config: Configuration = {
mode: 'production',
cache: {
Expand Down Expand Up @@ -52,6 +52,32 @@ function configFor(target: 'web' | 'node', pkg?: string): Configuration {
},
};

switch (output) {
case 'umd': {
config.output = {
filename: `[name]/${target}/umd/index.min.js`,
path: resolve(__dirname, 'lib'),
library: { type: 'umd' },
publicPath: '',
};
break;
}
case 'esm': {
config.output = {
module: true,
filename: `[name]/${target}/esm/index.min.js`,
path: resolve(__dirname, 'lib'),
library: { type: 'module' },
};
config.experiments = {
outputModule: true,
};
break;
}
default:
throw new Error('Unsupported output');
}

if (!pkg) {
config.entry = {
dapp: resolve(__dirname, './ts-src/dapp.ts'),
Expand All @@ -66,4 +92,8 @@ function configFor(target: 'web' | 'node', pkg?: string): Configuration {
return config;
}

export default (env: WebpackEnv) => [configFor('web', env.package), configFor('node', env.package)];
export default (env: WebpackEnv) => [
configFor('web', 'umd', env.package),
configFor('node', 'umd', env.package),
configFor('web', 'esm', env.package),
];
7 changes: 7 additions & 0 deletions packages/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## Unreleased

## 11.1.1

### Fixed

- An issue where WASM functionality could not be used when using the browser UMD library, orin a web context
without applying the bundler optimization.

## 11.1.0

### Added
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@concordium/web-sdk",
"version": "11.1.0",
"version": "11.1.1",
"license": "Apache-2.0",
"engines": {
"node": ">=16"
Expand Down
2 changes: 2 additions & 0 deletions packages/sdk/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ function configFor(target: 'web' | 'node' | 'react-native'): webpack.Configurati
},
},
module: {
// Don't parse the rust-bindings UMD bundles - they are self-contained with WASM initialization
noParse: /rust-bindings\/lib\/.*\/umd\/index\.min\.js$/,
rules: [
{
test: /\.tsx?$/,
Expand Down