diff --git a/examples/4-minimal-with-webhook/package.json b/examples/4-minimal-with-webhook/package.json
index 07f2573..734a0d1 100644
--- a/examples/4-minimal-with-webhook/package.json
+++ b/examples/4-minimal-with-webhook/package.json
@@ -5,7 +5,7 @@
"main": "index.js",
"type": "module",
"scripts": {
- "start": "node index.js",
+ "start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
diff --git a/examples/4-minimal-with-webhook/views/index.ejs b/examples/4-minimal-with-webhook/views/index.ejs
index 1d0678f..bc3f6f7 100644
--- a/examples/4-minimal-with-webhook/views/index.ejs
+++ b/examples/4-minimal-with-webhook/views/index.ejs
@@ -4,7 +4,7 @@
- Code SDK - Example/3-minimal-with-webhook
+ Code SDK - Example/4-minimal-with-webhook
diff --git a/examples/6-minimal-with-login/package.json b/examples/6-minimal-with-login/package.json
new file mode 100644
index 0000000..cff700f
--- /dev/null
+++ b/examples/6-minimal-with-login/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "6-minimal-with-login",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "type": "module",
+ "scripts": {
+ "start": "node server.js",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@code-wallet/client": "^1.1.0",
+ "body-parser": "^1.20.2",
+ "ejs": "^3.1.9",
+ "express": "^4.18.2"
+ },
+ "devDependencies": {
+ "@types/express": "^4.17.17"
+ }
+}
diff --git a/examples/6-minimal-with-login/server.js b/examples/6-minimal-with-login/server.js
new file mode 100644
index 0000000..fddce0a
--- /dev/null
+++ b/examples/6-minimal-with-login/server.js
@@ -0,0 +1,70 @@
+import * as code from "@code-wallet/client";
+import { Keypair } from "@code-wallet/library";
+import express from "express";
+
+const port = process.env.PORT || 3000;
+const hostname = process.env.HOSTNAME || 'example.com';
+const app = express();
+const verifier = Keypair.generate();
+
+// Set the view engine to ejs
+app.set('view engine', 'ejs');
+
+// index page (with the payment button)
+app.get('/', function(req, res) {
+ res.render('index');
+});
+
+// This is a page that the user will be redirected to once the payment is made.
+app.get('/success/:id', async (req, res) => {
+ // Get the payment intent id from the URL
+ const intent = req.params.id;
+
+ // Get the status of the payment intent and the user's public key
+ const status = await code.paymentIntents.getStatus({ intent });
+
+ // Render the success page with the intent id and status
+ res.render('success', { intent, status });
+});
+
+// This is a JSON file that Code will look for when verifying your domain. It
+// should be publicly accessible at the root of your domain. For example:
+// https://example.com/.well-known/code-payments.json
+app.get('/.well-known/code-payments.json', (req, res) => {
+ res.json({ "public_keys": [verifier.getPublicKey().toBase58()] });
+});
+
+// Create a payment intent. We're letting Code know that a payment is coming
+// soon and we want to be notified once it's made.
+app.post('/create-intent', async (req, res) => {
+
+ const { clientSecret, id } = await code.paymentIntents.create({
+ amount: 0.05,
+ currency: 'usd',
+ destination: 'E8otxw1CVX9bfyddKu3ZB3BVLa4VVF9J7CTPdnUwT9jR',
+
+ login: {
+ verifier: verifier.getPublicKey().toBase58(),
+
+ // Cannot be localhost or a subdomain. It must be a domain that you own
+ // and have access to. Code will verify that this domain is owned by you
+ // by looking for the .well-known/code-payments.json file.
+ domain: hostname,
+ },
+
+ signers: [ verifier ]
+ });
+
+ console.log('Created intent', id);
+
+ // The clientSecret value needs to be sent to the browser so that the browser
+ // can use it to setup a payment with this intent instance. The client will
+ // use the payment details along with this value to derive the same payment
+ // intent id on its end.
+ res.send({ clientSecret });
+});
+
+app.listen(port, () => {
+ console.log(`🚀 Minimal example listening on port ${port}`)
+ console.log(`http://localhost:${port}`)
+});
diff --git a/examples/6-minimal-with-login/views/index.ejs b/examples/6-minimal-with-login/views/index.ejs
new file mode 100644
index 0000000..cc60371
--- /dev/null
+++ b/examples/6-minimal-with-login/views/index.ejs
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ Code SDK - Example/6-minimal-with-login
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/6-minimal-with-login/views/success.ejs b/examples/6-minimal-with-login/views/success.ejs
new file mode 100644
index 0000000..a163b0f
--- /dev/null
+++ b/examples/6-minimal-with-login/views/success.ejs
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ Code SDK - Example/6-minimal-with-login
+
+
+
+ Payment Submitted
+ Intent Id: <%= intent %>
+
+
+
+
\ No newline at end of file
diff --git a/examples/package-lock.json b/examples/package-lock.json
index 9ef36fd..d73dd86 100644
--- a/examples/package-lock.json
+++ b/examples/package-lock.json
@@ -15,10 +15,11 @@
}
},
"../packages/client": {
- "version": "1.0.1",
+ "name": "@code-wallet/client",
+ "version": "1.1.0",
"license": "MIT",
"dependencies": {
- "@code-wallet/library": "^1.0.0",
+ "@code-wallet/library": "^1.1.0",
"bs58": "^5.0.0",
"buffer": "6.0.3"
},
@@ -59,7 +60,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
- "@code-wallet/client": "file:../../packages/client",
+ "@code-wallet/client": "^1.0.0",
"body-parser": "^1.20.2",
"ejs": "^3.1.9",
"express": "^4.18.2"
@@ -72,7 +73,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
- "@code-wallet/client": "file:../../packages/client",
+ "@code-wallet/client": "^1.0.0",
"body-parser": "^1.20.2",
"ejs": "^3.1.9",
"express": "^4.18.2"
@@ -108,6 +109,19 @@
"ts-node-dev": "^2.0.0"
}
},
+ "6-minimal-with-login": {
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@code-wallet/client": "^1.1.0",
+ "body-parser": "^1.20.2",
+ "ejs": "^3.1.9",
+ "express": "^4.18.2"
+ },
+ "devDependencies": {
+ "@types/express": "^4.17.17"
+ }
+ },
"node_modules/@babel/parser": {
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
@@ -534,6 +548,10 @@
"resolved": "5-example-purchase-flow",
"link": true
},
+ "node_modules/6-minimal-with-login": {
+ "resolved": "6-minimal-with-login",
+ "link": true
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -2084,7 +2102,7 @@
"@code-wallet/client": {
"version": "file:../packages/client",
"requires": {
- "@code-wallet/library": "^1.0.0",
+ "@code-wallet/library": "^1.1.0",
"@types/chai": "^4.3.5",
"@types/mocha": "^10.0.1",
"@types/node": "^20.5.7",
@@ -2450,7 +2468,7 @@
"3-minimal-with-verify": {
"version": "file:3-minimal-with-verify",
"requires": {
- "@code-wallet/client": "file:../../packages/client",
+ "@code-wallet/client": "^1.0.0",
"@types/express": "^4.17.17",
"body-parser": "^1.20.2",
"ejs": "^3.1.9",
@@ -2460,7 +2478,7 @@
"4-minimal-with-webhook": {
"version": "file:4-minimal-with-webhook",
"requires": {
- "@code-wallet/client": "file:../../packages/client",
+ "@code-wallet/client": "^1.0.0",
"@types/express": "^4.17.17",
"body-parser": "^1.20.2",
"ejs": "^3.1.9",
@@ -2491,6 +2509,16 @@
"vue": "^3.3.4"
}
},
+ "6-minimal-with-login": {
+ "version": "file:6-minimal-with-login",
+ "requires": {
+ "@code-wallet/client": "^1.1.0",
+ "@types/express": "^4.17.17",
+ "body-parser": "^1.20.2",
+ "ejs": "^3.1.9",
+ "express": "^4.18.2"
+ }
+ },
"accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
diff --git a/package-lock.json b/package-lock.json
index dc1e010..a01e1e9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3903,10 +3903,10 @@
},
"packages/client": {
"name": "@code-wallet/client",
- "version": "1.1.0",
+ "version": "1.1.1",
"license": "MIT",
"dependencies": {
- "@code-wallet/library": "^1.1.0",
+ "@code-wallet/library": "^1.1.1",
"bs58": "^5.0.0",
"buffer": "6.0.3"
},
@@ -3972,7 +3972,7 @@
},
"packages/library": {
"name": "@code-wallet/library",
- "version": "1.1.0",
+ "version": "1.1.1",
"license": "MIT",
"dependencies": {
"@code-wallet/rpc": "^1.1.0",
@@ -4098,7 +4098,7 @@
"@code-wallet/client": {
"version": "file:packages/client",
"requires": {
- "@code-wallet/library": "^1.1.0",
+ "@code-wallet/library": "^1.1.1",
"@types/chai": "^4.3.5",
"@types/mocha": "^10.0.1",
"@types/node": "^20.5.7",
diff --git a/packages/client/package.json b/packages/client/package.json
index 92862e8..47d01dd 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -1,6 +1,6 @@
{
"name": "@code-wallet/client",
- "version": "1.1.0",
+ "version": "1.1.1",
"license": "MIT",
"repository": {
"type": "git",
@@ -22,7 +22,7 @@
"maintained node versions"
],
"dependencies": {
- "@code-wallet/library": "^1.1.0",
+ "@code-wallet/library": "^1.1.1",
"bs58": "^5.0.0",
"buffer": "6.0.3"
},
diff --git a/packages/library/package.json b/packages/library/package.json
index 0ed16f3..430bc16 100644
--- a/packages/library/package.json
+++ b/packages/library/package.json
@@ -1,6 +1,6 @@
{
"name": "@code-wallet/library",
- "version": "1.1.0",
+ "version": "1.1.1",
"license": "MIT",
"repository": {
"type": "git",
diff --git a/packages/library/src/elements/validate.ts b/packages/library/src/elements/validate.ts
index 3f05f01..6b8db94 100644
--- a/packages/library/src/elements/validate.ts
+++ b/packages/library/src/elements/validate.ts
@@ -13,7 +13,7 @@ import {
ErrNotImplemented,
ErrInvalidValue,
} from '../errors';
-import { Keypair, PublicKey } from '../keys';
+import { PublicKey } from '../keys';
/**
* Validates the properties of the given `ElementOptions` for intents.
@@ -96,7 +96,7 @@ function validateSigners(intent: ElementOptions) {
if (!intent.signers) { return; }
for (const signer of intent.signers) {
- if (!(signer instanceof Keypair)) {
+ if (!signer.sign && typeof signer.sign !== 'function') {
throw ErrInvalidValue();
}
}
diff --git a/packages/library/src/intents/PaymentRequestWithLoginIntent.ts b/packages/library/src/intents/PaymentRequestWithLoginIntent.ts
index 539703a..51c4e53 100644
--- a/packages/library/src/intents/PaymentRequestWithLoginIntent.ts
+++ b/packages/library/src/intents/PaymentRequestWithLoginIntent.ts
@@ -102,17 +102,17 @@ class PaymentRequestWithLoginIntent extends PaymentRequestIntent {
throw ErrLoginVerifierRequired();
}
- const msg = this.toProto();
- const req = msg.kind.value as proto.RequestToReceiveBill;
- if (!req) {
+ const envelope = this.toProto();
+ const msg = envelope.kind.value as proto.RequestToReceiveBill;
+ if (!msg) {
throw ErrUnexpectedError();
}
- req.signature = new proto.Common.Signature({
- value: this.signer.sign(req.toBinary()),
+ msg.signature = new proto.Common.Signature({
+ value: this.signer.sign(msg.toBinary()),
});
- const sig = this.rendezvousKeypair.sign(msg.toBinary());
+ const sig = this.rendezvousKeypair.sign(envelope.toBinary());
const intent = this.rendezvousKeypair.getPublicKey().toBase58();
const message = msg.toBinary();
const signature = sig;
diff --git a/packages/library/test/payment_request_with_login.test.ts b/packages/library/test/payment_request_with_login.test.ts
index eebe9f4..4a1883c 100644
--- a/packages/library/test/payment_request_with_login.test.ts
+++ b/packages/library/test/payment_request_with_login.test.ts
@@ -183,30 +183,28 @@ describe('PaymentRequestWithLoginIntent', () => {
intent.rendezvousKeypair = rendezvous;
const res = intent.sign();
- const msg = proto.Message.fromBinary(res.message);
+ const msg = proto.RequestToReceiveBill.fromBinary(res.message);
expect(msg.toJson()).to.deep.equal({
- requestToReceiveBill: {
- requestorAccount: {
- value: PublicKey.fromBase58(destination).toBuffer().toString('base64')
- },
- partial: {
- currency: 'usd',
- nativeAmount: 0.5,
- },
- domain: {
- value: domain
- },
- verifier: {
- value: verifier.getPublicKey().toBuffer().toString('base64')
- },
- rendezvousKey: {
- value: rendezvous.getPublicKey().toBuffer().toString('base64')
- },
- signature: {
- value: '7EdpP8TSajVJ+79X0yCmG5FAlIlpJEO8Qsvo4CuSwyOLsJMXMqb15TrVyrFiNINEYHWfxpzJvwNkvrdiZT74Dg=='
- },
- }
+ requestorAccount: {
+ value: PublicKey.fromBase58(destination).toBuffer().toString('base64')
+ },
+ partial: {
+ currency: 'usd',
+ nativeAmount: 0.5,
+ },
+ domain: {
+ value: domain
+ },
+ verifier: {
+ value: verifier.getPublicKey().toBuffer().toString('base64')
+ },
+ rendezvousKey: {
+ value: rendezvous.getPublicKey().toBuffer().toString('base64')
+ },
+ signature: {
+ value: '7EdpP8TSajVJ+79X0yCmG5FAlIlpJEO8Qsvo4CuSwyOLsJMXMqb15TrVyrFiNINEYHWfxpzJvwNkvrdiZT74Dg=='
+ },
});
});
@@ -223,32 +221,32 @@ describe('PaymentRequestWithLoginIntent', () => {
intent.rendezvousKeypair = rendezvous;
const res = intent.sign();
- const msg = proto.Message.fromBinary(res.message);
+ const msg = proto.RequestToReceiveBill.fromBinary(res.message);
const actual = msg.toBinary();
const expected = new Uint8Array([
- 0x2a, 0xd3, 0x01, 0x0a, 0x22, 0x0a, 0x20, 0xab, 0x88, 0x67,
- 0x2f, 0x94, 0x4e, 0xa4, 0x5b, 0x3c, 0x25, 0xc2, 0x6d, 0x73,
- 0x2d, 0x2e, 0x5e, 0x40, 0xd5, 0xc7, 0xc1, 0x62, 0xc3, 0xcd,
- 0x68, 0x58, 0xd5, 0xc9, 0x5a, 0x23, 0xfa, 0x34, 0x55, 0x1a,
- 0x0e, 0x0a, 0x03, 0x75, 0x73, 0x64, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x22, 0x11, 0x0a, 0x0f, 0x61,
- 0x70, 0x70, 0x2e, 0x67, 0x65, 0x74, 0x63, 0x6f, 0x64, 0x65,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2a, 0x22, 0x0a, 0x20, 0x90, 0x5c,
- 0xc7, 0x96, 0xae, 0x7a, 0x19, 0x98, 0x46, 0x18, 0x36, 0xcd,
- 0x9f, 0x59, 0x05, 0x2f, 0x8a, 0x2a, 0x52, 0xcd, 0x53, 0x9b,
- 0x41, 0x7e, 0x57, 0x7c, 0x11, 0x82, 0x83, 0xd2, 0xa0, 0x6c,
- 0x32, 0x42, 0x0a, 0x40, 0xec, 0x47, 0x69, 0x3f, 0xc4, 0xd2,
- 0x6a, 0x35, 0x49, 0xfb, 0xbf, 0x57, 0xd3, 0x20, 0xa6, 0x1b,
- 0x91, 0x40, 0x94, 0x89, 0x69, 0x24, 0x43, 0xbc, 0x42, 0xcb,
- 0xe8, 0xe0, 0x2b, 0x92, 0xc3, 0x23, 0x8b, 0xb0, 0x93, 0x17,
- 0x32, 0xa6, 0xf5, 0xe5, 0x3a, 0xd5, 0xca, 0xb1, 0x62, 0x34,
- 0x83, 0x44, 0x60, 0x75, 0x9f, 0xc6, 0x9c, 0xc9, 0xbf, 0x03,
- 0x64, 0xbe, 0xb7, 0x62, 0x65, 0x3e, 0xf8, 0x0e, 0x3a, 0x22,
- 0x0a, 0x20, 0x70, 0xa4, 0xae, 0xb6, 0x8f, 0x76, 0x36, 0x3f,
- 0x22, 0x66, 0x81, 0xdf, 0x16, 0x62, 0xbf, 0xc0, 0xf6, 0x42,
- 0x36, 0xe9, 0x7a, 0x7a, 0x64, 0x87, 0x46, 0x6a, 0x93, 0x99,
- 0x54, 0x5e, 0x7a, 0xfb
+ 0x0a, 0x22, 0x0a, 0x20, 0xab, 0x88, 0x67, 0x2f, 0x94, 0x4e,
+ 0xa4, 0x5b, 0x3c, 0x25, 0xc2, 0x6d, 0x73, 0x2d, 0x2e, 0x5e,
+ 0x40, 0xd5, 0xc7, 0xc1, 0x62, 0xc3, 0xcd, 0x68, 0x58, 0xd5,
+ 0xc9, 0x5a, 0x23, 0xfa, 0x34, 0x55, 0x1a, 0x0e, 0x0a, 0x03,
+ 0x75, 0x73, 0x64, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe0, 0x3f, 0x22, 0x11, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x2e,
+ 0x67, 0x65, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2a, 0x22, 0x0a, 0x20, 0x90, 0x5c, 0xc7, 0x96, 0xae,
+ 0x7a, 0x19, 0x98, 0x46, 0x18, 0x36, 0xcd, 0x9f, 0x59, 0x05,
+ 0x2f, 0x8a, 0x2a, 0x52, 0xcd, 0x53, 0x9b, 0x41, 0x7e, 0x57,
+ 0x7c, 0x11, 0x82, 0x83, 0xd2, 0xa0, 0x6c, 0x32, 0x42, 0x0a,
+ 0x40, 0xec, 0x47, 0x69, 0x3f, 0xc4, 0xd2, 0x6a, 0x35, 0x49,
+ 0xfb, 0xbf, 0x57, 0xd3, 0x20, 0xa6, 0x1b, 0x91, 0x40, 0x94,
+ 0x89, 0x69, 0x24, 0x43, 0xbc, 0x42, 0xcb, 0xe8, 0xe0, 0x2b,
+ 0x92, 0xc3, 0x23, 0x8b, 0xb0, 0x93, 0x17, 0x32, 0xa6, 0xf5,
+ 0xe5, 0x3a, 0xd5, 0xca, 0xb1, 0x62, 0x34, 0x83, 0x44, 0x60,
+ 0x75, 0x9f, 0xc6, 0x9c, 0xc9, 0xbf, 0x03, 0x64, 0xbe, 0xb7,
+ 0x62, 0x65, 0x3e, 0xf8, 0x0e, 0x3a, 0x22, 0x0a, 0x20, 0x70,
+ 0xa4, 0xae, 0xb6, 0x8f, 0x76, 0x36, 0x3f, 0x22, 0x66, 0x81,
+ 0xdf, 0x16, 0x62, 0xbf, 0xc0, 0xf6, 0x42, 0x36, 0xe9, 0x7a,
+ 0x7a, 0x64, 0x87, 0x46, 0x6a, 0x93, 0x99, 0x54, 0x5e, 0x7a,
+ 0xfb
]);
expect(actual.toString()).to.equal(expected.toString());