From 3674d18a0f97bc1148c5f8a1478e822e7e74d244 Mon Sep 17 00:00:00 2001 From: Alexey Tsymbal Date: Wed, 3 Apr 2024 19:14:48 +0300 Subject: [PATCH] sdk: retire luxon dependency --- .../aptos-ed25519-payload-token-generator.ts | 5 +- ...load-authentication-facade-factory.spec.ts | 7 +- ...5519-authentication-facade-factory.spec.ts | 11 ++- ...5519-authentication-facade-factory.spec.ts | 12 +-- packages/blockchain-sdk-solana/CHANGELOG.md | 4 + .../examples/create-dapp-2.ts | 33 ++++++++ .../examples/create-dapp.ts | 76 +++++++++++++++++++ .../examples/e2e-dapp-server.ts | 46 ++++++++++- .../examples/generate-solana-token.ts | 5 +- packages/blockchain-sdk-solana/package.json | 2 +- .../src/auth/tx/solana-tx-token-generator.ts | 5 +- ...5519-authentication-facade-factory.spec.ts | 16 ++-- ...a-tx-authentication-facade-factory.spec.ts | 11 ++- packages/sdk/CHANGELOG.md | 4 + packages/sdk/package.json | 4 +- .../sdk/src/auth/authentication-facade.ts | 5 +- .../sdk/src/auth/default-token-generator.ts | 5 +- .../ed25519-authentication-facade.spec.ts | 13 ++-- packages/sdk/src/auth/token-generator.ts | 7 +- packages/sdk/src/auth/token-provider.ts | 17 ++--- packages/sdk/src/internal/sdk/sdk-factory.ts | 9 +-- .../tests/auth/cached-token-provider.spec.ts | 3 +- yarn.lock | 10 --- 23 files changed, 219 insertions(+), 91 deletions(-) create mode 100644 packages/blockchain-sdk-solana/examples/create-dapp-2.ts create mode 100644 packages/blockchain-sdk-solana/examples/create-dapp.ts diff --git a/packages/blockchain-sdk-aptos/src/auth/ed25519-payload/aptos-ed25519-payload-token-generator.ts b/packages/blockchain-sdk-aptos/src/auth/ed25519-payload/aptos-ed25519-payload-token-generator.ts index 5b065722..0ccbd883 100644 --- a/packages/blockchain-sdk-aptos/src/auth/ed25519-payload/aptos-ed25519-payload-token-generator.ts +++ b/packages/blockchain-sdk-aptos/src/auth/ed25519-payload/aptos-ed25519-payload-token-generator.ts @@ -1,4 +1,3 @@ -import type { Duration } from 'luxon'; import type { Token } from '@dialectlabs/sdk'; import { bytesToBase64, @@ -7,11 +6,11 @@ import { } from '@dialectlabs/sdk'; export class AptosEd25519PayloadTokenGenerator extends TokenGenerator { - override async generate(ttl: Duration): Promise { + override async generate(ttlSeconds: number): Promise { const header = this.header(); const base64Header = jsonStringifyToBase64(header); - const body = this.body(ttl); + const body = this.body(ttlSeconds); const base64Body = jsonStringifyToBase64(body); const { signature, base64Signature, signedPayload } = await this.sign( diff --git a/packages/blockchain-sdk-aptos/tests/auth/ed25519-payload/aptos-ed25519-payload-authentication-facade-factory.spec.ts b/packages/blockchain-sdk-aptos/tests/auth/ed25519-payload/aptos-ed25519-payload-authentication-facade-factory.spec.ts index ca19bf9f..9844fcc2 100644 --- a/packages/blockchain-sdk-aptos/tests/auth/ed25519-payload/aptos-ed25519-payload-authentication-facade-factory.spec.ts +++ b/packages/blockchain-sdk-aptos/tests/auth/ed25519-payload/aptos-ed25519-payload-authentication-facade-factory.spec.ts @@ -1,4 +1,3 @@ -import { Duration } from 'luxon'; import { DialectAptosWalletAdapterWrapper } from '../../../src/wallet-adapter/dialect-aptos-wallet-adapter-wrapper'; import { AptosEd25519PayloadTokenSigner, @@ -35,7 +34,7 @@ describe('aptos ed25519 payload token tests', () => { test('when not expired validation returns true', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then const isValid = authenticationFacade.isValid(token); @@ -48,7 +47,7 @@ describe('aptos ed25519 payload token tests', () => { test('when expired validation returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: -100 }), + -100, ); // then const isValid = authenticationFacade.isValid(token); @@ -79,7 +78,7 @@ describe('aptos ed25519 payload token tests', () => { ).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then expect(token.body.sub).toBe(sub); diff --git a/packages/blockchain-sdk-aptos/tests/auth/ed25519/aptos-ed25519-authentication-facade-factory.spec.ts b/packages/blockchain-sdk-aptos/tests/auth/ed25519/aptos-ed25519-authentication-facade-factory.spec.ts index fc43e719..45cb7472 100644 --- a/packages/blockchain-sdk-aptos/tests/auth/ed25519/aptos-ed25519-authentication-facade-factory.spec.ts +++ b/packages/blockchain-sdk-aptos/tests/auth/ed25519/aptos-ed25519-authentication-facade-factory.spec.ts @@ -1,4 +1,3 @@ -import { Duration } from 'luxon'; import { DialectAptosWalletAdapterWrapper } from '../../../src/wallet-adapter/dialect-aptos-wallet-adapter-wrapper'; import { AptosEd25519TokenSigner, @@ -30,7 +29,7 @@ describe('aptos ed25519 token tests', () => { test('when not expired validation returns true', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then const isValid = authenticationFacade.isValid(token); @@ -43,7 +42,7 @@ describe('aptos ed25519 token tests', () => { test('when expired validation returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: -100 }), + -100, ); // then const isValid = authenticationFacade.isValid(token); @@ -56,7 +55,7 @@ describe('aptos ed25519 token tests', () => { test('when sub compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60, ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -80,7 +79,7 @@ describe('aptos ed25519 token tests', () => { test('when sub jwk compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60 ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -104,7 +103,7 @@ describe('aptos ed25519 token tests', () => { test('when exp compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60 ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); diff --git a/packages/blockchain-sdk-evm/tests/auth/ed25519/evm-ed25519-authentication-facade-factory.spec.ts b/packages/blockchain-sdk-evm/tests/auth/ed25519/evm-ed25519-authentication-facade-factory.spec.ts index 348198c5..a1c32f0f 100644 --- a/packages/blockchain-sdk-evm/tests/auth/ed25519/evm-ed25519-authentication-facade-factory.spec.ts +++ b/packages/blockchain-sdk-evm/tests/auth/ed25519/evm-ed25519-authentication-facade-factory.spec.ts @@ -1,5 +1,4 @@ import { DialectEvmWalletAdapterWrapper } from '../../../src/wallet-adapter/dialect-evm-wallet-adapter-wrapper'; -import { Duration } from 'luxon'; import type { AuthenticationFacade, TokenBody } from '@dialectlabs/sdk'; import { NodeDialectEvmWalletAdapter } from '../../../src/wallet-adapter/node-evm-wallet-adapter'; import { @@ -27,7 +26,7 @@ describe('evm ed25519 token tests', () => { test('when not expired validation returns true', async () => { const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 10000 }), + 10000, ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -39,7 +38,7 @@ describe('evm ed25519 token tests', () => { test('when expired validation returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: -100 }), + -100 , ); // then const isValid = authenticationFacade.isValid(token); @@ -52,7 +51,7 @@ describe('evm ed25519 token tests', () => { test('when sub compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60, ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -78,7 +77,8 @@ describe('evm ed25519 token tests', () => { test('when sub jwk compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60, + ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -104,7 +104,7 @@ describe('evm ed25519 token tests', () => { test('when exp compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60, ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); diff --git a/packages/blockchain-sdk-solana/CHANGELOG.md b/packages/blockchain-sdk-solana/CHANGELOG.md index d85c6f9f..0ea002be 100644 --- a/packages/blockchain-sdk-solana/CHANGELOG.md +++ b/packages/blockchain-sdk-solana/CHANGELOG.md @@ -2,6 +2,10 @@ ## [UNRELEASED] +## [1.1.1] - 2024-04-03 + +- chore: retire luxon +- ## [1.1.0] - feat: retire on-chain messaging api diff --git a/packages/blockchain-sdk-solana/examples/create-dapp-2.ts b/packages/blockchain-sdk-solana/examples/create-dapp-2.ts new file mode 100644 index 00000000..659a9532 --- /dev/null +++ b/packages/blockchain-sdk-solana/examples/create-dapp-2.ts @@ -0,0 +1,33 @@ +import { BlockchainType, Dialect } from '../../sdk'; +import { NodeDialectSolanaWalletAdapter, Solana, SolanaSdkFactory } from '..'; +import { Keypair } from '@solana/web3.js'; +import bs58 from 'bs58'; + +async function main() { + const dappSdk = Dialect.sdk( + { + // environment: 'development', + environment: 'development', + }, + SolanaSdkFactory.create({ + wallet: new NodeDialectSolanaWalletAdapter( + Keypair.fromSecretKey( + new Uint8Array([ + 244, 13, 185, 49, 29, 25, 61, 3, 216, 244, 38, 117, 66, 91, 59, 109, + 33, 187, 247, 207, 94, 224, 47, 109, 94, 88, 111, 19, 245, 96, 152, + 158, 87, 102, 228, 178, 98, 12, 204, 105, 85, 77, 199, 40, 157, 149, + 87, 116, 196, 136, 33, 174, 123, 117, 87, 81, 48, 255, 116, 67, 134, + 14, 243, 204, + ]), + ), + ), + }), + ); + + const created = await dappSdk.dapps.create({ + name: 'Dialectooors dapp', + blockchainType: BlockchainType.SOLANA, + }); +} + +main().catch(console.error); diff --git a/packages/blockchain-sdk-solana/examples/create-dapp.ts b/packages/blockchain-sdk-solana/examples/create-dapp.ts new file mode 100644 index 00000000..d2bd14a2 --- /dev/null +++ b/packages/blockchain-sdk-solana/examples/create-dapp.ts @@ -0,0 +1,76 @@ +import { BlockchainType, Dialect } from '../../sdk'; +import { NodeDialectSolanaWalletAdapter, Solana, SolanaSdkFactory } from '..'; +import { Keypair } from '@solana/web3.js'; +import bs58 from 'bs58'; + +async function main() { + const monitor = Dialect.sdk( + { + // environment: 'development', + environment: 'development', + }, + SolanaSdkFactory.create({ + wallet: new NodeDialectSolanaWalletAdapter( + Keypair.fromSecretKey( + new Uint8Array([ + 56, 111, 31, 152, 56, 138, 122, 34, 150, 99, 14, 65, 41, 148, 28, + 58, 223, 101, 10, 31, 12, 146, 175, 132, 212, 6, 19, 222, 92, 177, + 36, 123, 65, 246, 202, 251, 197, 105, 179, 188, 65, 163, 200, 12, + 235, 148, 133, 28, 213, 61, 233, 180, 235, 110, 52, 2, 94, 136, 193, + 46, 225, 253, 48, 144, + ]), + ), + ), + }), + ); + const uint8Array = new Uint8Array([ + 248, 80, 183, 221, 66, 144, 97, 254, 75, 101, 186, 117, 33, 130, 91, 117, + 214, 195, 11, 209, 227, 230, 64, 138, 128, 91, 90, 248, 47, 46, 201, 100, 4, + 1, 253, 87, 233, 66, 232, 136, 133, 117, 185, 11, 43, 114, 187, 61, 35, 102, + 45, 78, 9, 6, 60, 136, 233, 210, 41, 32, 18, 228, 241, 182, + ]); + + const s = bs58.encode(uint8Array); + console.log(s); + const monitor2 = Dialect.sdk( + { + // environment: 'development', + environment: 'development', + }, + SolanaSdkFactory.create({ + wallet: new NodeDialectSolanaWalletAdapter( + Keypair.fromSecretKey(uint8Array), + ), + }), + ); + + const monitorDapp = await monitor.dapps.find(); + if (!monitorDapp) { + const created = await monitor.dapps.create({ + name: 'MONITOR 1', + blockchainType: BlockchainType.SOLANA, + }); + } + + const monitorDapp2 = await monitor2.dapps.find(); + if (!monitorDapp2) { + const created = await monitor2.dapps.create({ + name: 'MONITOR 2', + blockchainType: BlockchainType.SOLANA, + }); + } + + await monitorDapp2!.messages.send({ + title: 'Hello topic', + message: 'Hello from monitor 2 topic', + actions: [ + { + label: 'авыф', + url: 'https://www.figma.com', + }, + ], + notificationTypeId: '9b153418-f804-498d-9ea3-08f62359032a', + }); +} + +main().catch(console.error); diff --git a/packages/blockchain-sdk-solana/examples/e2e-dapp-server.ts b/packages/blockchain-sdk-solana/examples/e2e-dapp-server.ts index f43cf281..7c09874c 100644 --- a/packages/blockchain-sdk-solana/examples/e2e-dapp-server.ts +++ b/packages/blockchain-sdk-solana/examples/e2e-dapp-server.ts @@ -23,18 +23,58 @@ import { const sdk: DialectSdk = Dialect.sdk( { environment: 'production', + dialectCloud: {} }, SolanaSdkFactory.create({ wallet: NodeDialectSolanaWalletAdapter.create(), // don't forget to set DIALECT_SDK_CREDENTIALS env var to dapp wallet private key }), ); +const dapp = await sdk.dapps.find(); + +if (!dapp) { + console.error('Dapp not found. Please register a dapp first.'); + process.exit(1); +} +await dapp.messages.send({ + title: 'New notification', + message: 'Hello, from the dialect sdk example!', + actions: [ + { + label: 'Open Dialect', + url: 'https://dialect.io', + }, + ], +}); + console.log(`Server wallet address: ${sdk.wallet.address}`); async function main() { - // First, we register the sending keypair as a "dapp" (this is any project that wants to - // have users subscribe to receive notifications). - const dapp = await getOrRegisterDapp(); + const sdk: DialectSdk = Dialect.sdk( + { + environment: 'production', + }, + SolanaSdkFactory.create({ + wallet: NodeDialectSolanaWalletAdapter.create(), // don't forget to set DIALECT_SDK_CREDENTIALS env var to dapp wallet private key + }), + ); + + const dapp = await sdk.dapps.find(); + + if (!dapp) { + console.error('Dapp not found. Please register a dapp first.'); + process.exit(1); + } + await dapp.messages.send({ + title: 'New notification', + message: 'Hello, from the dialect sdk example!', + actions: [ + { + label: 'Open Dialect', + url: 'https://dialect.io', + }, + ], + }); console.log(`Dapp id: ${dapp.id}`); diff --git a/packages/blockchain-sdk-solana/examples/generate-solana-token.ts b/packages/blockchain-sdk-solana/examples/generate-solana-token.ts index 6d704419..5c5c6dae 100644 --- a/packages/blockchain-sdk-solana/examples/generate-solana-token.ts +++ b/packages/blockchain-sdk-solana/examples/generate-solana-token.ts @@ -4,7 +4,6 @@ import { NodeDialectSolanaWalletAdapter, SolanaEd25519AuthenticationFacadeFactory, } from '@dialectlabs/blockchain-sdk-solana'; -import { Duration } from 'luxon'; const adapter = NodeDialectSolanaWalletAdapter.create(); const walletAdapter = DialectSolanaWalletAdapterWrapper.create(adapter); @@ -16,8 +15,6 @@ const walletAdapter = DialectSolanaWalletAdapterWrapper.create(adapter); const authenticationFacade = new SolanaEd25519AuthenticationFacadeFactory( signer, ).get(); - const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 120 }), - ); + const token = await authenticationFacade.generateToken(120 * 60); console.log(token.rawValue); })(); diff --git a/packages/blockchain-sdk-solana/package.json b/packages/blockchain-sdk-solana/package.json index 135f568e..4d672e67 100644 --- a/packages/blockchain-sdk-solana/package.json +++ b/packages/blockchain-sdk-solana/package.json @@ -1,6 +1,6 @@ { "name": "@dialectlabs/blockchain-sdk-solana", - "version": "1.1.0", + "version": "1.1.1", "repository": "git@github.com:dialectlabs/sdk.git", "author": "dialectlabs", "license": "Apache-2.0", diff --git a/packages/blockchain-sdk-solana/src/auth/tx/solana-tx-token-generator.ts b/packages/blockchain-sdk-solana/src/auth/tx/solana-tx-token-generator.ts index 64b4eb09..8f49676d 100644 --- a/packages/blockchain-sdk-solana/src/auth/tx/solana-tx-token-generator.ts +++ b/packages/blockchain-sdk-solana/src/auth/tx/solana-tx-token-generator.ts @@ -1,4 +1,3 @@ -import type { Duration } from 'luxon'; import type { Token } from '@dialectlabs/sdk'; import { bytesToBase64, @@ -7,11 +6,11 @@ import { } from '@dialectlabs/sdk'; export class SolanaTxTokenGenerator extends TokenGenerator { - override async generate(ttl: Duration): Promise { + override async generate(ttlSeconds: number): Promise { const header = this.header(); const base64Header = jsonStringifyToBase64(header); - const body = this.body(ttl); + const body = this.body(ttlSeconds); const base64Body = jsonStringifyToBase64(body); const { signature, base64Signature, signedPayload } = await this.sign( diff --git a/packages/blockchain-sdk-solana/tests/auth/ed25519/solana-ed25519-authentication-facade-factory.spec.ts b/packages/blockchain-sdk-solana/tests/auth/ed25519/solana-ed25519-authentication-facade-factory.spec.ts index a51ebfd6..7d9e72ab 100644 --- a/packages/blockchain-sdk-solana/tests/auth/ed25519/solana-ed25519-authentication-facade-factory.spec.ts +++ b/packages/blockchain-sdk-solana/tests/auth/ed25519/solana-ed25519-authentication-facade-factory.spec.ts @@ -1,5 +1,4 @@ import { Keypair } from '@solana/web3.js'; -import { Duration } from 'luxon'; import { DialectSolanaWalletAdapterWrapper } from '../../../src/wallet-adapter/dialect-solana-wallet-adapter-wrapper'; import type { AccountAddress, @@ -36,7 +35,7 @@ describe('solana ed25519 token tests', () => { test('when not expired validation returns true', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100 ); // then const isValid = authenticationFacade.isValid(token); @@ -49,7 +48,7 @@ describe('solana ed25519 token tests', () => { test('when expired validation returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: -100 }), + -100 ); // then const isValid = authenticationFacade.isValid(token); @@ -62,7 +61,7 @@ describe('solana ed25519 token tests', () => { test('when sub compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60 ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -86,7 +85,8 @@ describe('solana ed25519 token tests', () => { test('when exp compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60 + ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -115,7 +115,7 @@ describe('solana ed25519 token tests', () => { ).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100 ); // then expect(token.body.sub).toBe(wallet.publicKey.toString()); @@ -137,7 +137,7 @@ describe('solana ed25519 token tests', () => { ).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100 ); // then expect(token.body.sub).toBe(subjectPublicKey.toString()); @@ -161,7 +161,7 @@ describe('solana ed25519 token tests', () => { ).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100 ); // then expect(token.body.sub).toBe(wallet.publicKey.toString()); diff --git a/packages/blockchain-sdk-solana/tests/auth/tx/solana-tx-authentication-facade-factory.spec.ts b/packages/blockchain-sdk-solana/tests/auth/tx/solana-tx-authentication-facade-factory.spec.ts index e4c9205b..1e435e83 100644 --- a/packages/blockchain-sdk-solana/tests/auth/tx/solana-tx-authentication-facade-factory.spec.ts +++ b/packages/blockchain-sdk-solana/tests/auth/tx/solana-tx-authentication-facade-factory.spec.ts @@ -9,7 +9,6 @@ import { } from '../../../src/auth/tx/solana-tx-token-signer'; import { SolanaTxAuthenticationFacadeFactory } from '../../../src/auth/tx/solana-tx-authentication-facade-factory'; -import { Duration } from 'luxon'; import type { AuthenticationFacade } from '@dialectlabs/sdk'; import { AccountAddress, @@ -36,7 +35,7 @@ describe('solana-tx token tests', () => { test('when not expired validation returns true', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then const isValid = authenticationFacade.isValid(token); @@ -49,7 +48,7 @@ describe('solana-tx token tests', () => { test('when expired validation returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: -100 }), + -100, ); // then const isValid = authenticationFacade.isValid(token); @@ -67,7 +66,7 @@ describe('solana-tx token tests', () => { ).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then expect(token.body.sub).toBe(wallet.publicKey.toString()); @@ -89,7 +88,7 @@ describe('solana-tx token tests', () => { ).get(); // when / then await expect( - authenticationFacade.generateToken(Duration.fromObject({ seconds: 100 })), + authenticationFacade.generateToken(100), ).rejects.toThrowError(); }); @@ -105,7 +104,7 @@ describe('solana-tx token tests', () => { ).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then expect(token.body.sub).toBe(wallet.publicKey.toString()); diff --git a/packages/sdk/CHANGELOG.md b/packages/sdk/CHANGELOG.md index 7b0528a4..3471ca41 100644 --- a/packages/sdk/CHANGELOG.md +++ b/packages/sdk/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## [1.7.3] - 2024-04-03 + +- chore: retire luxon + ## [1.7.2] - 2024-03-12 - feature: fix version number diff --git a/packages/sdk/package.json b/packages/sdk/package.json index ccf832eb..089495fa 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@dialectlabs/sdk", - "version": "1.7.2", + "version": "1.7.3", "repository": "git@github.com:dialectlabs/sdk.git", "author": "dialectlabs", "license": "Apache-2.0", @@ -30,7 +30,6 @@ "@solana/web3.js": "^1.53.0", "@types/bs58": "^4.0.1", "@types/ed2curve": "^0.2.2", - "@types/luxon": "^2.3.2", "mockdate": "^3.0.5" }, "dependencies": { @@ -39,7 +38,6 @@ "bs58": "^5.0.0", "ed2curve": "^0.3.0", "js-sha3": "^0.8.0", - "luxon": "^2.4.0", "nanoid": "^3.3.4", "tweetnacl": "^1.0.3" } diff --git a/packages/sdk/src/auth/authentication-facade.ts b/packages/sdk/src/auth/authentication-facade.ts index a2029667..1c6ae600 100644 --- a/packages/sdk/src/auth/authentication-facade.ts +++ b/packages/sdk/src/auth/authentication-facade.ts @@ -1,7 +1,6 @@ import type { TokenGenerator } from './token-generator'; import type { TokenValidator } from './token-validator'; import type { TokenParser } from './token-parser'; -import type { Duration } from 'luxon'; import type { AccountAddress, Token, @@ -48,8 +47,8 @@ export class AuthenticationFacade { return this.tokenSigner.subject; } - generateToken(ttl: Duration) { - return this.tokenGenerator.generate(ttl); + generateToken(ttlSeconds: number) { + return this.tokenGenerator.generate(ttlSeconds); } parseToken(token: string) { diff --git a/packages/sdk/src/auth/default-token-generator.ts b/packages/sdk/src/auth/default-token-generator.ts index d9d2f439..f82596cb 100644 --- a/packages/sdk/src/auth/default-token-generator.ts +++ b/packages/sdk/src/auth/default-token-generator.ts @@ -1,14 +1,13 @@ import type { Token } from './auth.interface'; -import type { Duration } from 'luxon'; import { jsonStringifyToBase64 } from '../utils/bytes-utils'; import { TokenGenerator } from './token-generator'; export class DefaultTokenGenerator extends TokenGenerator { - override async generate(ttl: Duration): Promise { + override async generate(ttlSeconds: number): Promise { const header = this.header(); const base64Header = jsonStringifyToBase64(header); - const body = this.body(ttl); + const body = this.body(ttlSeconds); const base64Body = jsonStringifyToBase64(body); const { signature, base64Signature } = await this.sign( diff --git a/packages/sdk/src/auth/ed25519/ed25519-authentication-facade.spec.ts b/packages/sdk/src/auth/ed25519/ed25519-authentication-facade.spec.ts index 6f84f103..367345e8 100644 --- a/packages/sdk/src/auth/ed25519/ed25519-authentication-facade.spec.ts +++ b/packages/sdk/src/auth/ed25519/ed25519-authentication-facade.spec.ts @@ -1,4 +1,3 @@ -import { Duration } from 'luxon'; import { Ed25519TokenSigner } from './ed25519-token-signer'; import type { AuthenticationFacade } from '../authentication-facade'; @@ -18,7 +17,7 @@ describe('ed25519 token tests', () => { test('when not expired validation returns true', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then const isValid = authenticationFacade.isValid(token); @@ -31,7 +30,7 @@ describe('ed25519 token tests', () => { test('when expired validation returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: -100 }), + -100, ); // then const isValid = authenticationFacade.isValid(token); @@ -44,7 +43,7 @@ describe('ed25519 token tests', () => { test('when sub compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 6 * 60, ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -71,7 +70,7 @@ describe('ed25519 token tests', () => { test('when exp compromised returns false', async () => { // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ minutes: 5 }), + 5 * 60, ); const isValid = authenticationFacade.isValid(token); expect(isValid).toBeTruthy(); @@ -107,7 +106,7 @@ describe('ed25519 token tests', () => { authenticationFacade = new Ed25519AuthenticationFacadeFactory(signer).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then expect(token.body.sub_jwk).not.toBe(token.body.sub); @@ -128,7 +127,7 @@ describe('ed25519 token tests', () => { authenticationFacade = new Ed25519AuthenticationFacadeFactory(signer).get(); // when const token = await authenticationFacade.generateToken( - Duration.fromObject({ seconds: 100 }), + 100, ); // then expect(token.body.sub).toBe(signerPublicKey.toString()); diff --git a/packages/sdk/src/auth/token-generator.ts b/packages/sdk/src/auth/token-generator.ts index f8a378b0..c09a366f 100644 --- a/packages/sdk/src/auth/token-generator.ts +++ b/packages/sdk/src/auth/token-generator.ts @@ -1,4 +1,3 @@ -import type { Duration } from 'luxon'; import { bytesToBase64 } from '../utils/bytes-utils'; import type { Token, @@ -10,7 +9,7 @@ import type { export abstract class TokenGenerator { constructor(protected readonly signer: TokenSigner) {} - abstract generate(ttl: Duration): Promise; + abstract generate(ttlSeconds: number): Promise; protected header(): TokenHeader { return { @@ -19,13 +18,13 @@ export abstract class TokenGenerator { }; } - protected body(ttl: Duration): TokenBody { + protected body(ttlSeconds: number): TokenBody { const nowUtcSeconds = new Date().getTime() / 1000; const body: TokenBody = { sub: this.signer.subject, sub_jwk: this.signer.subjectPublicKey?.toString(), iat: Math.round(nowUtcSeconds), - exp: Math.round(nowUtcSeconds + ttl.toMillis() / 1000), + exp: Math.round(nowUtcSeconds + ttlSeconds), }; return body; } diff --git a/packages/sdk/src/auth/token-provider.ts b/packages/sdk/src/auth/token-provider.ts index 522c81d7..34c75da8 100644 --- a/packages/sdk/src/auth/token-provider.ts +++ b/packages/sdk/src/auth/token-provider.ts @@ -1,6 +1,5 @@ import type { AccountAddress, Token } from './auth.interface'; import { IllegalArgumentError } from '../sdk/errors'; -import { Duration } from 'luxon'; import { TokenStore } from './token-store'; import type { TokenParser } from './token-parser'; import type { TokenValidator } from './token-validator'; @@ -9,19 +8,19 @@ import type { TokenGenerator } from './token-generator'; import type { DataServiceWalletsApiClientV1 } from '../dialect-cloud-api/data-service-wallets-api.v1'; import type { WalletCreation } from '../sdk/sdk.interface'; -export const DEFAULT_TOKEN_LIFETIME = Duration.fromObject({ days: 1 }); -export const MAX_TOKEN_LIFETIME = Duration.fromObject({ months: 4 }); +export const DEFAULT_TOKEN_LIFETIME_SECONDS = 24 * 60 * 60; // 24 hours +export const MAX_TOKEN_LIFETIME_SECONDS = 3 * 30 * 24 * 60 * 60; // 3 months export abstract class TokenProvider { static create( authenticationFacade: AuthenticationFacade, dataServiceWalletsApiClientV1: DataServiceWalletsApiClientV1, - ttl: Duration = DEFAULT_TOKEN_LIFETIME, + ttlSeconds = DEFAULT_TOKEN_LIFETIME_SECONDS, tokenStore: TokenStore = TokenStore.createInMemory(), walletCreation: WalletCreation = 'implicit', ): TokenProvider { const defaultTokenProvider = new DefaultTokenProvider( - ttl, + ttlSeconds, authenticationFacade.tokenGenerator, ); return new CachedTokenProvider( @@ -40,19 +39,19 @@ export abstract class TokenProvider { export class DefaultTokenProvider extends TokenProvider { constructor( - private readonly ttl: Duration, + private readonly ttlSeconds: number, private readonly tokenGenerator: TokenGenerator, ) { - if (ttl.toMillis() > MAX_TOKEN_LIFETIME.toMillis()) { + if (ttlSeconds > MAX_TOKEN_LIFETIME_SECONDS) { throw new IllegalArgumentError( - `Token TTL ${ttl.toHuman()} must be <= ${MAX_TOKEN_LIFETIME.toHuman()}`, + `Token TTL ${ttlSeconds} must be <= max ${MAX_TOKEN_LIFETIME_SECONDS}`, ); } super(); } get(): Promise { - return this.tokenGenerator.generate(this.ttl); + return this.tokenGenerator.generate(this.ttlSeconds); } } diff --git a/packages/sdk/src/internal/sdk/sdk-factory.ts b/packages/sdk/src/internal/sdk/sdk-factory.ts index 21a4f800..fbf8fca6 100644 --- a/packages/sdk/src/internal/sdk/sdk-factory.ts +++ b/packages/sdk/src/internal/sdk/sdk-factory.ts @@ -12,7 +12,7 @@ import type { import type { IdentityResolver } from '../../identity/identity.interface'; import { CachedTokenProvider, - DEFAULT_TOKEN_LIFETIME, + DEFAULT_TOKEN_LIFETIME_SECONDS, DefaultTokenProvider, TokenProvider, } from '../../auth/token-provider'; @@ -23,7 +23,6 @@ import type { Dapps, } from '../../dapp/dapp.interface'; import { DataServiceDappNotificationSubscriptions } from '../dapp/data-service-dapp-notification-subscriptions'; -import { Duration } from 'luxon'; import { DappMessagesFacade } from '../dapp/dapp-messages-facade'; import { DappsImpl } from '../dapp/dapp'; import { TokenStore } from '../../auth/token-store'; @@ -126,9 +125,7 @@ export class DialectSdkFactory { { authenticationFacade }: BlockchainSdk, ): CachedTokenProvider { const defaultTokenProvider = new DefaultTokenProvider( - Duration.fromObject({ - minutes: config.dialectCloud.tokenLifetimeMinutes, - }), + config.dialectCloud.tokenLifetimeMinutes * 60, authenticationFacade.tokenGenerator, ); const dataServiceWalletsApiV1 = new DataServiceWalletsApiClientV1( @@ -319,7 +316,7 @@ export class DialectSdkFactory { private createTokenLifetime() { return ( this.config.dialectCloud?.tokenLifetimeMinutes ?? - DEFAULT_TOKEN_LIFETIME.toMillis() / 1000 / 60 + DEFAULT_TOKEN_LIFETIME_SECONDS / 60 ); } diff --git a/packages/sdk/tests/auth/cached-token-provider.spec.ts b/packages/sdk/tests/auth/cached-token-provider.spec.ts index ecafa832..1f820a95 100644 --- a/packages/sdk/tests/auth/cached-token-provider.spec.ts +++ b/packages/sdk/tests/auth/cached-token-provider.spec.ts @@ -9,7 +9,6 @@ import { generateEd25519Keypair, TokenStore, } from '../../src'; -import { Duration } from 'luxon'; jest.mock('./../../src/dialect-cloud-api/data-service-wallets-api.v1'); @@ -118,7 +117,7 @@ describe('Cached token provider test', () => { ).get(); const defaultTokenProvider = new DefaultTokenProvider( - Duration.fromObject({ minutes: tokenValidityMinutes }), + tokenValidityMinutes * 60, authenticationFacade.tokenGenerator, ); const cachedTokenProvider = new CachedTokenProvider( diff --git a/yarn.lock b/yarn.lock index c45f251a..f4251379 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1840,11 +1840,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/luxon@^2.3.2": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-2.4.0.tgz#897d3abc23b68d78b69d76a12c21e01eb5adab95" - integrity sha512-oCavjEjRXuR6URJEtQm0eBdfsBiEcGBZbq21of8iGkeKxU1+1xgKuFPClaBZl2KB8ZZBSWlgk61tH6Mf+nvZVw== - "@types/node@*": version "20.4.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" @@ -5021,11 +5016,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -luxon@^2.4.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-2.5.2.tgz#17ed497f0277e72d58a4756d6a9abee4681457b6" - integrity sha512-Yg7/RDp4nedqmLgyH0LwgGRvMEKVzKbUdkBYyCosbHgJ+kaOUx0qzSiSatVc3DFygnirTPYnMM2P5dg2uH1WvA== - madge@^5.0.1: version "5.0.2" resolved "https://registry.yarnpkg.com/madge/-/madge-5.0.2.tgz#d34527af7e96de9625e8069902667c4c5a073ada"