From 1bbc35e6795644eeea88fddc37b48608c821890a Mon Sep 17 00:00:00 2001 From: Neal Date: Wed, 2 Oct 2024 14:49:20 -0700 Subject: [PATCH 1/6] add bundle --- .gitignore | 4 +++- bound/typescript/package.json | 4 ++-- bound/typescript/scripts/bundle.js | 19 ------------------- bound/typescript/scripts/bundle_tbdex.js | 23 +++++++++++++++++++++++ bound/typescript/scripts/bundle_wasm.js | 23 +++++++++++++++++++++++ bound/typescript/src/index.ts | 9 +++++++++ 6 files changed, 60 insertions(+), 22 deletions(-) delete mode 100644 bound/typescript/scripts/bundle.js create mode 100644 bound/typescript/scripts/bundle_tbdex.js create mode 100644 bound/typescript/scripts/bundle_wasm.js create mode 100644 bound/typescript/src/index.ts diff --git a/.gitignore b/.gitignore index 6a636efd..4779aca0 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,6 @@ dist/ pkg/ bound/typescript/src/wasm/generated.js bound/typescript/src/wasm/generated.d.ts -bound/typescript/tests/compiled \ No newline at end of file +bound/typescript/tests/compiled +bound/typescript/generate-mappings/node_modules/ +bound/typescript/node_modules/ \ No newline at end of file diff --git a/bound/typescript/package.json b/bound/typescript/package.json index 6e3e5309..ff410d95 100644 --- a/bound/typescript/package.json +++ b/bound/typescript/package.json @@ -33,8 +33,8 @@ }, "scripts": { "clean": "rimraf pkg tests/compiled dist", - "build:wasm": "./scripts/build.sh && node ./scripts/bundle.js && cp dist/bundle.js src/wasm/generated.js && cp dist/tbdex_wasm.d.ts src/wasm/generated.d.ts && (cd ./generate-mappings && npm run generate)", - "build": "tsc && cp -r src/wasm dist/bound/typescript/src", + "build:wasm": "./scripts/build.sh && node ./scripts/bundle_wasm.js && (cd ./generate-mappings && npm run generate)", + "build": "tsc && cp -r src/wasm dist/bound/typescript/src && node ./scripts/bundle_wasm.js", "test:node": "npm run build && node tests/bundle-node.js && mocha", "test:browser": "npm run build && node tests/bundle-browser.js && web-test-runner", "test": "npm run test:node && npm run test:browser" diff --git a/bound/typescript/scripts/bundle.js b/bound/typescript/scripts/bundle.js deleted file mode 100644 index 103968f4..00000000 --- a/bound/typescript/scripts/bundle.js +++ /dev/null @@ -1,19 +0,0 @@ -import { fileURLToPath } from 'node:url' - -import esbuild from 'esbuild' -import path from 'node:path' -import fs from 'node:fs' - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -esbuild.buildSync({ - format: 'esm', - bundle: true, - minify: true, - entryPoints: [`${__dirname}/../pkg/tbdex_wasm.js`], - outfile: `${__dirname}/../dist/bundle.js`, - allowOverwrite: true, -}) - -fs.copyFileSync(`${__dirname}/../pkg/tbdex_wasm.d.ts`, `${__dirname}/../dist/tbdex_wasm.d.ts`) diff --git a/bound/typescript/scripts/bundle_tbdex.js b/bound/typescript/scripts/bundle_tbdex.js new file mode 100644 index 00000000..0617dfb9 --- /dev/null +++ b/bound/typescript/scripts/bundle_tbdex.js @@ -0,0 +1,23 @@ +import { fileURLToPath } from 'node:url'; +import esbuild from 'esbuild'; +import path from 'node:path'; +import fs from 'node:fs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +esbuild.buildSync({ + entryPoints: [`${__dirname}/../src/index.ts`], + format: 'esm', // Output as ES module + bundle: true, // Bundle all dependencies + minify: true, // Minify the bundle for production + sourcemap: true, // Enable source map for debugging + outfile: `${__dirname}/../dist/index.js`, + target: 'esnext', // Target latest ECMAScript version + platform: 'node', // Target platform (Node.js) + external: ['node_modules/*'] // Exclude node modules from the bundle +}); + +// Optional: Copy additional assets like WASM files to the dist folder +fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); +fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); diff --git a/bound/typescript/scripts/bundle_wasm.js b/bound/typescript/scripts/bundle_wasm.js new file mode 100644 index 00000000..55f6fa19 --- /dev/null +++ b/bound/typescript/scripts/bundle_wasm.js @@ -0,0 +1,23 @@ +import { fileURLToPath } from 'node:url'; +import esbuild from 'esbuild'; +import path from 'node:path'; +import fs from 'node:fs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +esbuild.buildSync({ + entryPoints: [`${__dirname}/../src/index.ts`], // Entry point for your project + format: 'esm', // Output as ES module + bundle: true, // Bundle all dependencies + minify: true, // Minify the bundle for production + sourcemap: true, // Enable source map for debugging + outfile: `${__dirname}/../dist/index.js`, // Output file (bundled) + target: 'esnext', // Target latest ECMAScript version + platform: 'node', // Target platform (Node.js) + external: ['node_modules/*'] // Exclude node modules from the bundle +}); + +// Copy WASM files (if needed) +fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); +fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); diff --git a/bound/typescript/src/index.ts b/bound/typescript/src/index.ts new file mode 100644 index 00000000..d560abdf --- /dev/null +++ b/bound/typescript/src/index.ts @@ -0,0 +1,9 @@ +export * from './messages'; +export * from './resources'; +export * from './wasm'; + +export * from './bearer-did'; +export * from './errors'; +export * from './key-managers'; +export * from './portable-did'; +export * from './signers'; From 6d0252051c9f30d35d26657a9c2cde39216fa566 Mon Sep 17 00:00:00 2001 From: Neal Date: Thu, 3 Oct 2024 12:59:30 -0700 Subject: [PATCH 2/6] start of exemplar --- .gitignore | 3 +- bound/typescript/package.json | 12 +- bound/typescript/scripts/bundle_tbdex.js | 4 +- bound/typescript/scripts/bundle_wasm.js | 56 +- bound/typescript/src/index.ts | 17 +- bound/typescript/tsconfig.json | 12 +- examples/hosted-wallet-ts/.env | 4 + examples/hosted-wallet-ts/README.md | 11 + examples/hosted-wallet-ts/package-lock.json | 851 ++++++++++++++++++ examples/hosted-wallet-ts/package.json | 24 + .../hosted-wallet-ts/src/pfi/api/exchanges.ts | 36 + .../hosted-wallet-ts/src/pfi/api/offerings.ts | 19 + examples/hosted-wallet-ts/src/pfi/index.ts | 19 + .../src/wallet/flows/happyPathFlow.ts | 30 + examples/hosted-wallet-ts/src/wallet/index.ts | 36 + examples/hosted-wallet-ts/tsconfig.json | 13 + 16 files changed, 1114 insertions(+), 33 deletions(-) create mode 100644 examples/hosted-wallet-ts/.env create mode 100644 examples/hosted-wallet-ts/README.md create mode 100644 examples/hosted-wallet-ts/package-lock.json create mode 100644 examples/hosted-wallet-ts/package.json create mode 100644 examples/hosted-wallet-ts/src/pfi/api/exchanges.ts create mode 100644 examples/hosted-wallet-ts/src/pfi/api/offerings.ts create mode 100644 examples/hosted-wallet-ts/src/pfi/index.ts create mode 100644 examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts create mode 100644 examples/hosted-wallet-ts/src/wallet/index.ts create mode 100644 examples/hosted-wallet-ts/tsconfig.json diff --git a/.gitignore b/.gitignore index 4779aca0..6cc536dc 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,5 @@ bound/typescript/src/wasm/generated.js bound/typescript/src/wasm/generated.d.ts bound/typescript/tests/compiled bound/typescript/generate-mappings/node_modules/ -bound/typescript/node_modules/ \ No newline at end of file +bound/typescript/node_modules/ +examples/hosted-wallet-ts/node_modules/ \ No newline at end of file diff --git a/bound/typescript/package.json b/bound/typescript/package.json index ff410d95..8aaf17d2 100644 --- a/bound/typescript/package.json +++ b/bound/typescript/package.json @@ -4,17 +4,16 @@ "private": false, "type": "module", "description": "", - "types": "./dist/tbdex.d.ts", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "exports": { ".": { "import": "./dist/index.js", - "types": "./dist/tbdex.d.ts" + "types": "./dist/index.d.ts" } }, "files": [ - "./dist/index.js", - "./dist/bundle.js", - "./dist/tbdex.d.ts" + "dist" ], "devDependencies": { "@types/chai": "4.3.0", @@ -34,7 +33,8 @@ "scripts": { "clean": "rimraf pkg tests/compiled dist", "build:wasm": "./scripts/build.sh && node ./scripts/bundle_wasm.js && (cd ./generate-mappings && npm run generate)", - "build": "tsc && cp -r src/wasm dist/bound/typescript/src && node ./scripts/bundle_wasm.js", + "build": "tsc && cp -r src/wasm dist/bound/typescript/src && node ./scripts/bundle_tbdex.js", + "test:node": "npm run build && node tests/bundle-node.js && mocha", "test:browser": "npm run build && node tests/bundle-browser.js && web-test-runner", "test": "npm run test:node && npm run test:browser" diff --git a/bound/typescript/scripts/bundle_tbdex.js b/bound/typescript/scripts/bundle_tbdex.js index 0617dfb9..90f48ad2 100644 --- a/bound/typescript/scripts/bundle_tbdex.js +++ b/bound/typescript/scripts/bundle_tbdex.js @@ -19,5 +19,5 @@ esbuild.buildSync({ }); // Optional: Copy additional assets like WASM files to the dist folder -fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); -fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); +// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); +// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); diff --git a/bound/typescript/scripts/bundle_wasm.js b/bound/typescript/scripts/bundle_wasm.js index 55f6fa19..f853cef2 100644 --- a/bound/typescript/scripts/bundle_wasm.js +++ b/bound/typescript/scripts/bundle_wasm.js @@ -1,23 +1,43 @@ -import { fileURLToPath } from 'node:url'; -import esbuild from 'esbuild'; -import path from 'node:path'; -import fs from 'node:fs'; +import { fileURLToPath } from 'node:url' + +import esbuild from 'esbuild' +import path from 'node:path' +import fs from 'node:fs' const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); esbuild.buildSync({ - entryPoints: [`${__dirname}/../src/index.ts`], // Entry point for your project - format: 'esm', // Output as ES module - bundle: true, // Bundle all dependencies - minify: true, // Minify the bundle for production - sourcemap: true, // Enable source map for debugging - outfile: `${__dirname}/../dist/index.js`, // Output file (bundled) - target: 'esnext', // Target latest ECMAScript version - platform: 'node', // Target platform (Node.js) - external: ['node_modules/*'] // Exclude node modules from the bundle -}); - -// Copy WASM files (if needed) -fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); -fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); + format: 'esm', + bundle: true, + minify: true, + entryPoints: [`${__dirname}/../pkg/tbdex_wasm.js`], + outfile: `${__dirname}/../src/wasm/generated.js`, + allowOverwrite: true, +}) + +fs.copyFileSync(`${__dirname}/../pkg/tbdex_wasm.d.ts`, `${__dirname}/../src/wasm/generated.d.ts`) + +// import { fileURLToPath } from 'node:url'; +// import esbuild from 'esbuild'; +// import path from 'node:path'; +// import fs from 'node:fs'; + +// const __filename = fileURLToPath(import.meta.url); +// const __dirname = path.dirname(__filename); + +// esbuild.buildSync({ +// entryPoints: [`${__dirname}/../src/index.ts`], // Entry point for your project +// format: 'esm', // Output as ES module +// bundle: true, // Bundle all dependencies +// minify: true, // Minify the bundle for production +// sourcemap: true, // Enable source map for debugging +// outfile: `${__dirname}/../dist/index.js`, // Output file (bundled) +// target: 'esnext', // Target latest ECMAScript version +// platform: 'node', // Target platform (Node.js) +// external: ['node_modules/*'] // Exclude node modules from the bundle +// }); + +// // Copy WASM files (if needed) +// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); +// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); diff --git a/bound/typescript/src/index.ts b/bound/typescript/src/index.ts index d560abdf..3740e377 100644 --- a/bound/typescript/src/index.ts +++ b/bound/typescript/src/index.ts @@ -1,3 +1,18 @@ +// TODO: Generate this file automatically +export * from './messages/cancel'; +export * from './messages/cancel'; +export * from './messages/close'; +export * from './messages/order'; +export * from './messages/order-instructions'; +export * from './messages/order-status'; +export * from './messages/quote'; +export * from './messages/rfq'; + + +export * from './resources/balance' +export * from './resources/offering' + + export * from './messages'; export * from './resources'; export * from './wasm'; @@ -6,4 +21,4 @@ export * from './bearer-did'; export * from './errors'; export * from './key-managers'; export * from './portable-did'; -export * from './signers'; +export * from './signers'; \ No newline at end of file diff --git a/bound/typescript/tsconfig.json b/bound/typescript/tsconfig.json index 136f50f6..d298087c 100644 --- a/bound/typescript/tsconfig.json +++ b/bound/typescript/tsconfig.json @@ -7,13 +7,15 @@ "resolveJsonModule": true, "strict": true, "esModuleInterop": true, - "skipLibCheck": true + "skipLibCheck": true, + "declaration": true, + "declarationMap": true }, "include": [ - "src/**/*", - "tests/**/*" + "src/**/*" ], "exclude": [ - "node_modules" + "node_modules", + "tests" ] -} +} \ No newline at end of file diff --git a/examples/hosted-wallet-ts/.env b/examples/hosted-wallet-ts/.env new file mode 100644 index 00000000..5a6ab87a --- /dev/null +++ b/examples/hosted-wallet-ts/.env @@ -0,0 +1,4 @@ +PFI_DID_URI=did:example:pfi12345 +HOSTED_WALLET_VERIFIABLE_CREDENTIAL=your_verifiable_credential_here +HOSTED_WALLET_PORTABLE_DID_JSON={"uri":"did:example:wallet12345","document":{},"privateKeys":[]} +REPLY_TO_URL=http://localhost:8081/pfi-reply-to diff --git a/examples/hosted-wallet-ts/README.md b/examples/hosted-wallet-ts/README.md new file mode 100644 index 00000000..2f69eebf --- /dev/null +++ b/examples/hosted-wallet-ts/README.md @@ -0,0 +1,11 @@ +# hosted-wallet-ts + +This is a TypeScript implementation of the hosted wallet example, showcasing a simple end-to-end tbDEX exchange. + +## How-To + +### 1. Install Dependencies + +```bash +npm install +``` diff --git a/examples/hosted-wallet-ts/package-lock.json b/examples/hosted-wallet-ts/package-lock.json new file mode 100644 index 00000000..a8d3ccf1 --- /dev/null +++ b/examples/hosted-wallet-ts/package-lock.json @@ -0,0 +1,851 @@ +{ + "name": "hosted-wallet-ts", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hosted-wallet-ts", + "version": "1.0.0", + "dependencies": { + "axios": "^1.4.0", + "body-parser": "^1.20.2", + "dotenv": "^16.3.1", + "express": "^4.18.2", + "tbdex": "file:../../bound/typescript" + }, + "devDependencies": { + "@types/express": "^4.17.17", + "@types/node": "^20.4.2", + "typescript": "^5.1.6" + } + }, + "../../bound/typescript": { + "name": "tbdex", + "version": "0.1.0", + "devDependencies": { + "@types/chai": "4.3.0", + "@types/mocha": "9.1.0", + "@web/test-runner": "0.18.0", + "@web/test-runner-playwright": "0.11.0", + "base64url": "^3.0.1", + "chai": "4.3.10", + "esbuild": "0.19.9", + "mocha": "10.2.0", + "rimraf": "5.0.5", + "typescript": "^5.6.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.16.10", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/qs": { + "version": "6.9.16", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.7.7", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.0", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.13.0", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/send": { + "version": "0.19.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/tbdex": { + "resolved": "../../bound/typescript", + "link": true + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.6.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/examples/hosted-wallet-ts/package.json b/examples/hosted-wallet-ts/package.json new file mode 100644 index 00000000..df0ace75 --- /dev/null +++ b/examples/hosted-wallet-ts/package.json @@ -0,0 +1,24 @@ +{ + "name": "hosted-wallet-ts", + "version": "1.0.0", + "description": "A TypeScript implementation of the hosted wallet example", + "main": "dist/index.js", + "scripts": { + "build": "tsc", + "start:pfi": "node dist/pfi/index.js", + "start:wallet": "node dist/wallet/index.js" + }, + "dependencies": { + "axios": "^1.4.0", + "body-parser": "^1.20.2", + "dotenv": "^16.3.1", + "express": "^4.18.2", + "tbdex": "file:../../bound/typescript" + }, + "devDependencies": { + "@types/express": "^4.17.17", + "@types/node": "^20.4.2", + "typescript": "^5.1.6" + }, + "type": "module" +} diff --git a/examples/hosted-wallet-ts/src/pfi/api/exchanges.ts b/examples/hosted-wallet-ts/src/pfi/api/exchanges.ts new file mode 100644 index 00000000..337b043a --- /dev/null +++ b/examples/hosted-wallet-ts/src/pfi/api/exchanges.ts @@ -0,0 +1,36 @@ +import { Router } from 'express'; + +const router = Router(); + +router.get('/', (req, res) => { + console.log('GET /exchanges'); + // TODO: Implement logic to fetch exchange IDs + res.json({ + exchanges: [] + }); +}); + +router.get('/:id', (req, res) => { + const exchangeId = req.params.id; + console.log(`GET /exchanges/${exchangeId}`); + // TODO: Implement logic to fetch a specific exchange + res.json({ + exchangeId, + messages: [] + }); +}); + +router.post('/', (req, res) => { + console.log('POST /exchanges'); + // TODO: Implement logic to create an exchange + res.status(202).send(); +}); + +router.put('/:id', (req, res) => { + const exchangeId = req.params.id; + console.log(`PUT /exchanges/${exchangeId}`); + // TODO: Implement logic to update an exchange + res.status(202).send(); +}); + +export default router; diff --git a/examples/hosted-wallet-ts/src/pfi/api/offerings.ts b/examples/hosted-wallet-ts/src/pfi/api/offerings.ts new file mode 100644 index 00000000..e19860c7 --- /dev/null +++ b/examples/hosted-wallet-ts/src/pfi/api/offerings.ts @@ -0,0 +1,19 @@ +import { Router } from 'express'; + +const router = Router(); + +router.get('/', (req, res) => { + console.log('GET /offerings'); + // TODO: Implement logic to fetch offerings + res.json({ + offerings: [ + { + id: 'offering_01', + description: 'Fake offering 1', + // ...other offering details + } + ] + }); +}); + +export default router; diff --git a/examples/hosted-wallet-ts/src/pfi/index.ts b/examples/hosted-wallet-ts/src/pfi/index.ts new file mode 100644 index 00000000..3071de3e --- /dev/null +++ b/examples/hosted-wallet-ts/src/pfi/index.ts @@ -0,0 +1,19 @@ +import express from 'express'; +import dotenv from 'dotenv'; +import offeringsRouter from './api/offerings.js'; +import exchangesRouter from './api/exchanges.js'; + +dotenv.config(); + +const app = express(); +const PORT = 8082; + +app.use(express.json()); + +// Routes +app.use('/offerings', offeringsRouter); +app.use('/exchanges', exchangesRouter); + +app.listen(PORT, () => { + console.log(`PFI server running on port ${PORT}`); +}); diff --git a/examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts b/examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts new file mode 100644 index 00000000..4dce1043 --- /dev/null +++ b/examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts @@ -0,0 +1,30 @@ +import axios from 'axios'; +import { Message, Balance, Rfq } from "tbdex"; +import { BalanceData, CreateSelectedPayinMethod, PayinMethod } from "tbdex/dist/wasm/generated-mappings"; + +export const runHappyPathFlow = async ( + pfiDidUri: string, + verifiableCredential: string, + replyToUrl: string +) => { + console.log('\n ~Running Happy Path Webhook Flow~ \n'); + + const balanceData: BalanceData = {available: "av",currencyCode: "cc"}; + console.log(balanceData); + console.log("test finished"); + + // // TODO: Implement the flow logic + // console.log('1. Fetching offerings...'); + // try { + // const response = await axios.get(`${pfiDidUri}/offerings`); + // const offerings = response.data.offerings; + // console.log('Successfully fetched offerings:', offerings); + + // // Continue with the flow... + // } catch (error) { + // console.error('Error fetching offerings:', error); + // } + // }; +}; + + diff --git a/examples/hosted-wallet-ts/src/wallet/index.ts b/examples/hosted-wallet-ts/src/wallet/index.ts new file mode 100644 index 00000000..fed18399 --- /dev/null +++ b/examples/hosted-wallet-ts/src/wallet/index.ts @@ -0,0 +1,36 @@ +import dotenv from 'dotenv'; +import { runHappyPathFlow } from './flows/happyPathFlow.js'; + +dotenv.config(); + +enum ExchangeFlowType { + HAPPY_PATH_WEBHOOK_FLOW, + CANCEL_FLOW, + ERROR_FLOW, + ALL_FLOWS +} + +let FLOW_TYPE = ExchangeFlowType.HAPPY_PATH_WEBHOOK_FLOW; + +const pfiDidUri = process.env.PFI_DID_URI || ''; +const verifiableCredential = process.env.HOSTED_WALLET_VERIFIABLE_CREDENTIAL || ''; +const replyToUrl = process.env.REPLY_TO_URL || ''; + +switch (FLOW_TYPE) { + case ExchangeFlowType.HAPPY_PATH_WEBHOOK_FLOW: + runHappyPathFlow(pfiDidUri, verifiableCredential, replyToUrl); + break; + // case ExchangeFlowType.CANCEL_FLOW: + // // runCancelFlow(pfiDidUri, verifiableCredential, replyToUrl); + // break; + // case ExchangeFlowType.ERROR_FLOW: + // // runErrorFlow(pfiDidUri, verifiableCredential); + // break; + // case ExchangeFlowType.ALL_FLOWS: + // // runHappyPathFlow(pfiDidUri, verifiableCredential, replyToUrl); + // // runCancelFlow(pfiDidUri, verifiableCredential, replyToUrl); + // // runErrorFlow(pfiDidUri, verifiableCredential); + // break; + default: + console.log('Invalid flow type selected.'); +} diff --git a/examples/hosted-wallet-ts/tsconfig.json b/examples/hosted-wallet-ts/tsconfig.json new file mode 100644 index 00000000..069dc788 --- /dev/null +++ b/examples/hosted-wallet-ts/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "node", + "rootDir": "./src", + "outDir": "./dist", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true + }, + "include": ["src"] +} From c9ef7a5be365b1878ef8763201eff36be621f93c Mon Sep 17 00:00:00 2001 From: Neal Date: Thu, 3 Oct 2024 13:02:03 -0700 Subject: [PATCH 3/6] update --- bound/typescript/scripts/bundle_tbdex.js | 21 ++++++++----------- bound/typescript/scripts/bundle_wasm.js | 26 +----------------------- 2 files changed, 9 insertions(+), 38 deletions(-) diff --git a/bound/typescript/scripts/bundle_tbdex.js b/bound/typescript/scripts/bundle_tbdex.js index 90f48ad2..41a52ee8 100644 --- a/bound/typescript/scripts/bundle_tbdex.js +++ b/bound/typescript/scripts/bundle_tbdex.js @@ -1,23 +1,18 @@ import { fileURLToPath } from 'node:url'; import esbuild from 'esbuild'; import path from 'node:path'; -import fs from 'node:fs'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); esbuild.buildSync({ entryPoints: [`${__dirname}/../src/index.ts`], - format: 'esm', // Output as ES module - bundle: true, // Bundle all dependencies - minify: true, // Minify the bundle for production - sourcemap: true, // Enable source map for debugging + format: 'esm', + bundle: true, + minify: true, + sourcemap: true, outfile: `${__dirname}/../dist/index.js`, - target: 'esnext', // Target latest ECMAScript version - platform: 'node', // Target platform (Node.js) - external: ['node_modules/*'] // Exclude node modules from the bundle -}); - -// Optional: Copy additional assets like WASM files to the dist folder -// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); -// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); + target: 'esnext', + platform: 'node', + external: ['node_modules/*'] +}); \ No newline at end of file diff --git a/bound/typescript/scripts/bundle_wasm.js b/bound/typescript/scripts/bundle_wasm.js index f853cef2..6bc09023 100644 --- a/bound/typescript/scripts/bundle_wasm.js +++ b/bound/typescript/scripts/bundle_wasm.js @@ -16,28 +16,4 @@ esbuild.buildSync({ allowOverwrite: true, }) -fs.copyFileSync(`${__dirname}/../pkg/tbdex_wasm.d.ts`, `${__dirname}/../src/wasm/generated.d.ts`) - -// import { fileURLToPath } from 'node:url'; -// import esbuild from 'esbuild'; -// import path from 'node:path'; -// import fs from 'node:fs'; - -// const __filename = fileURLToPath(import.meta.url); -// const __dirname = path.dirname(__filename); - -// esbuild.buildSync({ -// entryPoints: [`${__dirname}/../src/index.ts`], // Entry point for your project -// format: 'esm', // Output as ES module -// bundle: true, // Bundle all dependencies -// minify: true, // Minify the bundle for production -// sourcemap: true, // Enable source map for debugging -// outfile: `${__dirname}/../dist/index.js`, // Output file (bundled) -// target: 'esnext', // Target latest ECMAScript version -// platform: 'node', // Target platform (Node.js) -// external: ['node_modules/*'] // Exclude node modules from the bundle -// }); - -// // Copy WASM files (if needed) -// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.js'), path.resolve(__dirname, '../dist/wasm/generated.js')); -// fs.copyFileSync(path.resolve(__dirname, '../src/wasm/generated.d.ts'), path.resolve(__dirname, '../dist/wasm/generated.d.ts')); +fs.copyFileSync(`${__dirname}/../pkg/tbdex_wasm.d.ts`, `${__dirname}/../src/wasm/generated.d.ts`) \ No newline at end of file From 72c9a9ea83354695c1a6e3014544c1f1ad75bdb7 Mon Sep 17 00:00:00 2001 From: Neal Date: Fri, 4 Oct 2024 10:18:08 -0700 Subject: [PATCH 4/6] fix build --- bound/typescript/package.json | 2 +- bound/typescript/scripts/bundle_tbdex.js | 32 ++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/bound/typescript/package.json b/bound/typescript/package.json index 8aaf17d2..6d95878d 100644 --- a/bound/typescript/package.json +++ b/bound/typescript/package.json @@ -33,7 +33,7 @@ "scripts": { "clean": "rimraf pkg tests/compiled dist", "build:wasm": "./scripts/build.sh && node ./scripts/bundle_wasm.js && (cd ./generate-mappings && npm run generate)", - "build": "tsc && cp -r src/wasm dist/bound/typescript/src && node ./scripts/bundle_tbdex.js", + "build": "tsc", "test:node": "npm run build && node tests/bundle-node.js && mocha", "test:browser": "npm run build && node tests/bundle-browser.js && web-test-runner", diff --git a/bound/typescript/scripts/bundle_tbdex.js b/bound/typescript/scripts/bundle_tbdex.js index 41a52ee8..30914e4c 100644 --- a/bound/typescript/scripts/bundle_tbdex.js +++ b/bound/typescript/scripts/bundle_tbdex.js @@ -1,18 +1,18 @@ -import { fileURLToPath } from 'node:url'; -import esbuild from 'esbuild'; -import path from 'node:path'; +// import { fileURLToPath } from 'node:url'; +// import esbuild from 'esbuild'; +// import path from 'node:path'; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +// const __filename = fileURLToPath(import.meta.url); +// const __dirname = path.dirname(__filename); -esbuild.buildSync({ - entryPoints: [`${__dirname}/../src/index.ts`], - format: 'esm', - bundle: true, - minify: true, - sourcemap: true, - outfile: `${__dirname}/../dist/index.js`, - target: 'esnext', - platform: 'node', - external: ['node_modules/*'] -}); \ No newline at end of file +// esbuild.buildSync({ +// entryPoints: [`${__dirname}/../src/index.ts`], +// format: 'esm', +// bundle: true, +// minify: true, +// sourcemap: true, +// outfile: `${__dirname}/../dist/index.js`, +// target: 'esnext', +// platform: 'node', +// external: ['node_modules/*'] +// }); \ No newline at end of file From f95da39038e2e084ada5e502c1681baaa6b33108 Mon Sep 17 00:00:00 2001 From: Neal Date: Fri, 4 Oct 2024 10:42:19 -0700 Subject: [PATCH 5/6] fix tests --- bound/typescript/tests/bundle-browser.js | 2 +- bound/typescript/tests/bundle-node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bound/typescript/tests/bundle-browser.js b/bound/typescript/tests/bundle-browser.js index 704e25a9..3ebba8d1 100644 --- a/bound/typescript/tests/bundle-browser.js +++ b/bound/typescript/tests/bundle-browser.js @@ -7,7 +7,7 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); esbuild.buildSync({ - entryPoints : [`${__dirname}/../dist/bound/typescript/tests/**/*.test.js`], + entryPoints: [`${__dirname}/*.test.ts`], format : 'esm', bundle : true, sourcemap : true, diff --git a/bound/typescript/tests/bundle-node.js b/bound/typescript/tests/bundle-node.js index 3c09cff4..4c7372a8 100644 --- a/bound/typescript/tests/bundle-node.js +++ b/bound/typescript/tests/bundle-node.js @@ -7,7 +7,7 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); esbuild.buildSync({ - entryPoints: [`${__dirname}/../dist/bound/typescript/tests/**/*.test.js`], + entryPoints: [`${__dirname}/*.test.ts`], format: 'esm', bundle: true, sourcemap: true, From deb76e67ff648357d94a6be77ec1bd476c52a37d Mon Sep 17 00:00:00 2001 From: Neal Date: Mon, 7 Oct 2024 12:01:04 -0700 Subject: [PATCH 6/6] WIP --- bound/typescript/src/index.ts | 28 +- .../hosted-wallet-ts/src/pfi/api/exchanges.ts | 363 ++++++++++++++++-- .../src/wallet/flows/happyPathFlow.ts | 2 +- 3 files changed, 356 insertions(+), 37 deletions(-) diff --git a/bound/typescript/src/index.ts b/bound/typescript/src/index.ts index 3740e377..c76e051c 100644 --- a/bound/typescript/src/index.ts +++ b/bound/typescript/src/index.ts @@ -1,4 +1,7 @@ // TODO: Generate this file automatically + +// messages +export * from './messages'; export * from './messages/cancel'; export * from './messages/cancel'; export * from './messages/close'; @@ -8,15 +11,32 @@ export * from './messages/order-status'; export * from './messages/quote'; export * from './messages/rfq'; - +// resources +export * from './resources'; export * from './resources/balance' export * from './resources/offering' - -export * from './messages'; -export * from './resources'; +// wasm export * from './wasm'; +// http +export * from './http/exchanges' +export * from './http/exchanges/create-exchange'; +export {GetExchangesResponseBody} from './http/exchanges/get-exchange-ids'; +export * from './http/exchanges/get-exchange'; +export * from './http/exchanges/reply-to'; +export * from './http/exchanges/update-exchange'; + + +export * from './http/balances' +export * from './http/offerings' + +// http-client +export * from './http-client/balances' +export * from './http-client/exchanges' +export * from './http-client/offerings' + +// web5 export * from './bearer-did'; export * from './errors'; export * from './key-managers'; diff --git a/examples/hosted-wallet-ts/src/pfi/api/exchanges.ts b/examples/hosted-wallet-ts/src/pfi/api/exchanges.ts index 337b043a..b3f453c0 100644 --- a/examples/hosted-wallet-ts/src/pfi/api/exchanges.ts +++ b/examples/hosted-wallet-ts/src/pfi/api/exchanges.ts @@ -1,36 +1,335 @@ import { Router } from 'express'; +import axios from 'axios'; +import { + BearerDid, + PortableDid, + Offering, + GetExchangeResponseBody, + tbdexError, + CreateExchangeRequestBody, + UpdateExchangeRequestBody, + ReplyToRequestBody, + TbdexError, + Quote, + OrderInstructions, + OrderStatus, + Close, + Rfq, + Order, + Cancel, + Message, + GetExchangesResponseBody + // Status, + // PaymentInstruction, +} from 'tbdex'; +// import { CloseData, OrderInstructionsData, OrderStatusData, PaymentInstruction, QuoteData } from 'tbdex/dist/wasm/generated-mappings'; -const router = Router(); -router.get('/', (req, res) => { - console.log('GET /exchanges'); - // TODO: Implement logic to fetch exchange IDs - res.json({ - exchanges: [] - }); -}); - -router.get('/:id', (req, res) => { - const exchangeId = req.params.id; - console.log(`GET /exchanges/${exchangeId}`); - // TODO: Implement logic to fetch a specific exchange - res.json({ - exchangeId, - messages: [] +// import { GetExchangesResponseBody } from 'tbdex/dist/http/exchanges/'; + +interface Exchange { + rfq?: Message; + quote?: Message; + order?: Message; + orderInstructions?: Message; + cancel?: Message; + close?: Message; + orderStatuses?: Message[]; +} + +function createExchangesRouter( + bearerDid: BearerDid, + offeringsRepository: any // Replace 'any' with the actual type +) { + const router = Router(); + + const exchangesToReplyTo: Map = new Map(); + const exchangeIdToExchange: Map = new Map(); + + router.get('/', (req, res) => { + console.log('GET /exchanges'); + + const offset = parseInt(req.query['page[offset]'] as string) || 0; + const limit = parseInt(req.query['page[limit]'] as string) || 10; + const exchangeIds = Array.from(exchangeIdToExchange.keys()); + const paginatedExchanges = exchangeIds.slice(offset, offset + limit); + + const bearerDID = BearerDid.fromPortableDID( + PortableDid.fromJSONString( + '{"uri":"did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0","document":{"id":"did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0","@context":["https://www.w3.org/ns/did/v1"],"verificationMethod":[{"id":"did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0#0","type":"JsonWebKey","controller":"did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0","publicKeyJwk":{"alg":"Ed25519","kty":"OKP","crv":"Ed25519","x":"iAuxCoarRaizG1ZH0zajTkrb_Pk-7zM-zFW4DA8AK5M"}}],"authentication":["did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0#0"],"assertionMethod":["did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0#0"],"capabilityInvocation":["did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0#0"],"capabilityDelegation":["did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJpQXV4Q29hclJhaXpHMVpIMHphalRrcmJfUGstN3pNLXpGVzREQThBSzVNIn0#0"]},"privateKeys":[{"alg":"Ed25519","kty":"OKP","crv":"Ed25519","d":"GSd8aUVcNX9O8ipqOV2gXJToHyzUZ_8mJrQ7G5UsmHs","x":"iAuxCoarRaizG1ZH0zajTkrb_Pk-7zM-zFW4DA8AK5M"}]}' + ) + ); + // const responseBody = new GetExchangesResponseBody(paginatedExchanges); + + res.type('application/json'); + // res.send(responseBody.toJSONString()); + res.send('hi'); }); -}); - -router.post('/', (req, res) => { - console.log('POST /exchanges'); - // TODO: Implement logic to create an exchange - res.status(202).send(); -}); - -router.put('/:id', (req, res) => { - const exchangeId = req.params.id; - console.log(`PUT /exchanges/${exchangeId}`); - // TODO: Implement logic to update an exchange - res.status(202).send(); -}); - -export default router; + + // router.get('/:id', (req, res) => { + // const exchangeId = req.params.id; + // console.log(`GET /exchanges/${exchangeId}`); + + // const exchange = exchangeIdToExchange.get(exchangeId); + // if (!exchange) { + // res.status(404).send('Exchange not found'); + // return; + // } + + // const messages = [ + // exchange.rfq, + // exchange.quote, + // exchange.order, + // exchange.orderInstructions, + // exchange.cancel, + // exchange.close, + // ...(exchange.orderStatuses || []), + // ].filter(Boolean); + + // const responseBody = new GetExchangeResponseBody(messages as Message[]); + + // res.type('application/json'); + // res.send(responseBody.toJSONString()); + // }); + + // router.post('/', (req, res) => { + // console.log('POST /exchanges'); + + // const requestBody = CreateExchangeRequestBody.fromJSONString(req.body); + // const rfq = requestBody.message as Rfq; + + // rfq.verify(); + + // try { + // rfq.verifyOfferingRequirements( + // offeringsRepository.getOffering(rfq.data.offeringId) + // ); + // } catch (e) { + // res.status(400); + // const errorResponseBody = new Error( + // 'RFQ does not satisfy an available offering' + // ); + // res.send(errorResponseBody); + // return; + // } + + // if (requestBody.replyTo) { + // exchangesToReplyTo.set(rfq.metadata.exchangeId, requestBody.replyTo); + // } + // exchangeIdToExchange.set(rfq.metadata.exchangeId, { rfq }); + + // res.status(202).send(); + + // setTimeout(() => { + // replyWithQuote(rfq.metadata.from, rfq.metadata.exchangeId); + // }, 500); + // }); + + // router.put('/:id', (req, res) => { + // const exchangeId = req.params.id; + // console.log(`PUT /exchanges/${exchangeId}`); + + // const updateExchangeRequestBody = UpdateExchangeRequestBody.fromJSONString( + // req.body + // ); + // const message = updateExchangeRequestBody.message; + + // if (message instanceof Order) { + // const orderMessage = message as Order; + // // Simulate order execution + // orderMessage.verify(); + + // setTimeout(() => { + // replyWithOrderInstructions( + // orderMessage.metadata.from, + // orderMessage.metadata.exchangeId + // ); + // setTimeout(() => { + // replyWithOrderStatus( + // orderMessage.metadata.from, + // orderMessage.metadata.exchangeId, + // 'PAYIN_INITIATED' + // ); + // setTimeout(() => { + // replyWithOrderStatus( + // orderMessage.metadata.from, + // orderMessage.metadata.exchangeId, + // 'PAYIN_SETTLED' + // ); + // setTimeout(() => { + // replyWithOrderStatus( + // orderMessage.metadata.from, + // orderMessage.metadata.exchangeId, + // 'PAYOUT_INITIATED' + // ); + // setTimeout(() => { + // replyWithOrderStatus( + // orderMessage.metadata.from, + // orderMessage.metadata.exchangeId, + // 'PAYOUT_SETTLED' + // ); + // setTimeout(() => { + // replyWithClose( + // orderMessage.metadata.from, + // orderMessage.metadata.exchangeId + // ); + // }, 500); + // }, 500); + // }, 500); + // }, 500); + // }, 500); + // }, 500); + // } else if (message instanceof Cancel) { + // const cancelMessage = message as Cancel; + // // Simulate cancel + // cancelMessage.verify(); + + // setTimeout(() => { + // replyWithClose( + // cancelMessage.metadata.from, + // cancelMessage.metadata.exchangeId, + // false + // ); + // }, 500); + // } + + // res.status(202).send(); + // }); + + // function replyWithQuote(to: string, exchangeId: string) { + // const quoteData: QuoteData = { + // expiresAt: '2024-08-02T04:26:08.239Z', + // payin: { + // currencyCode: 'BTC', + // subtotal: '1000.00', + // total: '1001.00', + // }, + // payout: { + // currencyCode: 'KES', + // subtotal: '1000.00', + // total: '1001.00', + // }, + // payoutUnitsPerPayinUnit: '1.0', + // }; + + // const quote = Quote.create(to, bearerDid.did.uri, exchangeId, quoteData); + + // quote.sign(bearerDid); + // quote.verify(); + + // console.log('Replying with quote'); + + // const existingExchange = exchangeIdToExchange.get(exchangeId) || {}; + // exchangeIdToExchange.set(exchangeId, { ...existingExchange, quote }); + + // const replyTo = exchangesToReplyTo.get(exchangeId); + // if (replyTo) { + // replyRequest(replyTo, new ReplyToRequestBody(quote)); + // } + // } + + // function replyWithOrderInstructions(to: string, exchangeId: string) { + // const payInPaymentInstruction: PaymentInstruction = {link: "http://tbd.website/payin", instruction: "payin instruction"}; + // const payOutPaymentInstruction: PaymentInstruction = {link: "http://tbd.website/payin", instruction: "payin instruction"}; + + + // const orderInstructionsData: OrderInstructionsData = {payin: payInPaymentInstruction, payout: payOutPaymentInstruction}; + + // const orderInstructions = OrderInstructions.create(to, bearerDid.did.uri, exchangeId, orderInstructionsData) + + // orderInstructions.sign(bearerDid); + // orderInstructions.verify(); + + // console.log('Replying with orderInstructions'); + + // const existingExchange = exchangeIdToExchange.get(exchangeId) || {}; + // exchangeIdToExchange.set(exchangeId, { + // ...existingExchange, + // orderInstructions, + // }); + + // const replyTo = exchangesToReplyTo.get(exchangeId); + // if (replyTo) { + // replyRequest(replyTo, new ReplyToRequestBody(orderInstructions)); + // } + // } + + // function replyWithOrderStatus( + // to: string, + // exchangeId: string, + // status: string + // ) { + + // const OrderStatusData: OrderStatusData = { + // status: status, + // } + + // const orderStatus = OrderStatus.create(to, bearerDid.did.uri, exchangeId, OrderStatusData); + + // orderStatus.sign(bearerDid); + // orderStatus.verify(); + + // console.log(`Replying with order status ${status}`); + + // const existingExchange = exchangeIdToExchange.get(exchangeId) || {}; + // const updatedOrderStatuses = existingExchange.orderStatuses || []; + // updatedOrderStatuses.push(orderStatus); + // exchangeIdToExchange.set(exchangeId, { + // ...existingExchange, + // orderStatuses: updatedOrderStatuses, + // }); + + // const replyTo = exchangesToReplyTo.get(exchangeId); + // if (replyTo) { + // replyRequest(replyTo, new ReplyToRequestBody(orderStatus)); + // } + // } + + // function replyWithClose( + // to: string, + // exchangeId: string, + // success: boolean = true + // ) { + + + // const closeData: CloseData = { + // success: true, + // } + + // const close = Close.create( + // to, + // bearerDid.did.uri, + // exchangeId, + // closeData + // ); + + // close.sign(bearerDid); + // close.verify(); + + // console.log('Replying with close'); + + // const existingExchange = exchangeIdToExchange.get(exchangeId) || {}; + // exchangeIdToExchange.set(exchangeId, { ...existingExchange, close }); + + // const replyTo = exchangesToReplyTo.get(exchangeId); + // if (replyTo) { + // replyRequest(replyTo, new ReplyToRequestBody(close)); + // } + // } + + // function replyRequest(replyTo: string, body: ReplyToRequestBody) { + // axios + // .post(replyTo, body.toJSONString(), { + // headers: { + // 'Content-Type': 'application/json; charset=utf-8', + // }, + // }) + // .catch((error) => { + // console.error('Error in replyRequest:', error); + // }); + // } + + return router; +} + +export default createExchangesRouter; \ No newline at end of file diff --git a/examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts b/examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts index 4dce1043..6f4ebb24 100644 --- a/examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts +++ b/examples/hosted-wallet-ts/src/wallet/flows/happyPathFlow.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { Message, Balance, Rfq } from "tbdex"; +import { Message, Balance, Rfq, CreateExchangeRequestBody } from "tbdex"; import { BalanceData, CreateSelectedPayinMethod, PayinMethod } from "tbdex/dist/wasm/generated-mappings"; export const runHappyPathFlow = async (