Skip to content

Commit

Permalink
Release v0.8.0 (#136)
Browse files Browse the repository at this point in the history
* chore: add jest setup to coverage all files (#101)

* refactor: fix circular import

* test: contract engine initial structure

* Contract Engine unit tests (#103)

* refactor: contract engine errors

* feat: validate required initialization arguments

* test: contract engine initialization workflow

* test: complete contract engine main coverage

* refactor: update deprecated methods

* refactor: contract engine errors (#104)

* Update docs and minor adjustments to jsdocs (#105)

* fix: missing error CE009

* docs: update jsdoc

* docs: update readme for public release

* packaging: bump version to 0.7.0 (#108)

* test: add build transaction unit tests

* chore: merge with develop

* test: add build transaction failure tests

* refactor: make networkConfig variable private

* test: add unit test for fee bump pipeline (#113)

* test: add unit tests for classic signature requirements pipeline (#115)

* Adjustments to release library as open source 🚀  (#107)

* chore: add jest setup to coverage all files (#101)

* refactor: fix circular import

* test: contract engine initial structure

* Contract Engine unit tests (#103)

* refactor: contract engine errors

* feat: validate required initialization arguments

* test: contract engine initialization workflow

* test: complete contract engine main coverage

* refactor: update deprecated methods

* refactor: contract engine errors (#104)

* Update docs and minor adjustments to jsdocs (#105)

* fix: missing error CE009

* docs: update jsdoc

* docs: update readme for public release

* packaging: bump version to 0.7.0 (#108)

---------

Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>

* fix: setoptions op threshold requirement

* fix: revoke operation variants threshold calculation

* test: add unit tests to classig sign requirements pipeline

* refactor: rearrange as per aaa pattern

---------

Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>

* Add unit tests for simulate transaction pipeline (#117)

* refactor: eslint adjustments

* test: initial simulate transaction unit tests

* feat: add assemble transaction sp error

* test: complete coverage for simulate transaction pipeline

* refactor: clean up comments and adjust imports

* Add unit tests for classic transaction pipeline (#118)

* test: add unit tests for classic transaction pipeline

* refactor: adjust imports

* test: add unit tests for soroban transaction pipeline (#119)

* test: add unit test for sign transaction pipeline

* test: add unit test for submit transaction pipeline

* Add unit tests soroban auth (#123)

* fix: remove validation from contract engine initialization

* style: remove comment

* feat: modify account handler mocker payload

* test: add unit test to soroban auth pipeline

---------

Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>

* Complete unit test coverage for account handlers (#125)

* test: add unit tests for the default account handler

* test: validate error to sign auth entry

* feat: add fee bump type to sign payload

* test: refactor freighter account handler unit tests

* Create test-coverage.yml action (#126)

* Create test-coverage.yml action

* Update test-coverage.yml

* Add unit test for base account handler (#127)

* test: add unit tests for the default account handler

* test: validate error to sign auth entry

* feat: add fee bump type to sign payload

* test: refactor freighter account handler unit tests

* test: add unit tests for base account handler

* Add unit test for soroban get transaction pipeline (#124)

* refactor: soroban get transaction pipeline constructor

* fix: remove old log

* test: add unit tests for soroban get transaction pipeline

* style: adjust imports

* Add unit tests for the classic asset handler (#128)

* refactor: adjust outter imports/exports

* test: add unit tests for the classic asset handler

* feat: remove issuer requirement for classic assets (#129)

* refactor: allow for no payload for dah

* feat: remove issuer necessity for classic assets to better include native

* test: add unit test to soroban token handler (#131)

* feat: remove helper classes for account (#132)

* feat: remove helper classes for account

* refactor: remove unused error for base account

* test: complete unit coverage for base account errors

* Standardize default network configs and custom (#133)

* feat: standardize network config options as functions under network

* test: adjust tests for new network config format

* feat: require rpc url for default rpc handler to initialize

* feat: require horizon url to initialize default horizon handler

* test: remove local testing from coverage

* feat: remove soroban client

* feat: convert horizon load account error to sp error

* feat: add allowhttp to network config

* test: add unit tests to default horizon handler

* test: add default rpc handler unit tests

* fix: account changes with network new config format

* test: add network configuration unit tests

* refactor: allowhttp object

Co-authored-by: Caio Teixeira <caio.xd63@hotmail.com>

---------

Co-authored-by: Caio Teixeira <caio.xd63@hotmail.com>

* packaging: bump version to v0.8.0

* Fix merge issues (#137)

* feat: standardize network config options as functions under network

* fix: duplicate imports

---------

Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>
Co-authored-by: Caio Teixeira <caio.xd63@hotmail.com>
  • Loading branch information
3 people authored Apr 25, 2024
1 parent a1b3158 commit b7a18c3
Show file tree
Hide file tree
Showing 69 changed files with 5,182 additions and 495 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["tsconfig.json"]
"project": ["tsconfig.json"],
"exclude": "commitlint.config.js"
},
"exclude": "commitlint.config.js",
"plugins": ["@typescript-eslint", "prettier", "unicorn", "import"],
"extends": [
"eslint:recommended",
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/test-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Node.js CI

on:
workflow_dispatch:
workflow_call:
push:
branches: [ "develop", "main" ]
pull_request:
branches: [ "develop", "main" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
cache-dependency-path: './package-lock.json'

- name: Install Dependencies
run: npm ci

- name: Run tests with coverage
run: npm test

- name: Code Coverage Report
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: ./src/coverage/cobertura-coverage.xml
fail_below_min: false
format: markdown
hide_branch_rate: false
hide_complexity: true
indicators: true
output: both
thresholds: '60 80'

- name: Add Coverage PR Comment
uses: marocchino/sticky-pull-request-comment@v2
if: github.event_name == 'pull_request'
with:
recreate: true
path: code-coverage-results.md
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stellar-plus",
"version": "0.7.0",
"version": "0.8.0",
"description": "beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
Expand Down
11 changes: 9 additions & 2 deletions src/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ module.exports = {
testEnvironment: 'node',
collectCoverage: true,
coverageReporters: ['cobertura', 'json', 'html', 'text'],
coveragePathIgnorePatterns: ['/node_modules/', '<rootDir>/*/.*\\.types.ts', '.*\\mocks.ts', './coverage/'],
collectCoverageFrom: ['./**/*.ts'],
collectCoverageFrom: [
'./**/*.ts',
'!<rootDir>/*/.*\\.types.ts',
'!<rootDir>/*/.*\\.mocks.ts',
'!<rootDir>/dist/',
'!/node_modules/',
'!/coverage/',
],
coveragePathIgnorePatterns: ['<rootDir>/index-test.ts'],
setupFilesAfterEnv: ['./setup-tests.ts'],
modulePathIgnorePatterns: ['<rootDir>/dist/'],
moduleDirectories: ['node_modules', 'src'],
Expand Down
11 changes: 5 additions & 6 deletions src/stellar-plus/account/account-handler/default/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { FeeBumpTransaction, Keypair, Transaction, authorizeEntry, xdr } from '@stellar/stellar-sdk'

import { DAHError } from 'stellar-plus/account/account-handler/default/errors'
import { DefaultAccountHandler, DefaultAccountHandlerPayload } from 'stellar-plus/account/account-handler/default/types'
import { AccountBaseClient } from 'stellar-plus/account/base'
import { AccountBase } from 'stellar-plus/account/base'
import { TransactionXdr } from 'stellar-plus/types'

import { DAHError } from './errors'

export class DefaultAccountHandlerClient extends AccountBaseClient implements DefaultAccountHandler {
export class DefaultAccountHandlerClient extends AccountBase implements DefaultAccountHandler {
protected secretKey: string

/**
Expand All @@ -16,8 +15,8 @@ export class DefaultAccountHandlerClient extends AccountBaseClient implements De
* @param {NetworkConfig} payload.networkConfig The network to use.
* @description - The default account handler is used for handling and creating new accounts by directly manipulating the secret key.
*/
constructor(payload: DefaultAccountHandlerPayload) {
const secretKey = payload.secretKey as string
constructor(payload?: DefaultAccountHandlerPayload) {
const secretKey = payload?.secretKey as string
try {
const keypair = secretKey ? Keypair.fromSecret(secretKey) : Keypair.random()

Expand Down
162 changes: 162 additions & 0 deletions src/stellar-plus/account/account-handler/default/index.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { FeeBumpTransaction, Keypair, Transaction, authorizeEntry, xdr } from '@stellar/stellar-sdk'

import { DefaultAccountHandlerClient } from 'stellar-plus/account/account-handler/default'
import { DAHError } from 'stellar-plus/account/account-handler/default/errors'
import { TestNet } from 'stellar-plus/network'

jest.mock('@stellar/stellar-sdk', () => {
// The mock doesnt spread the whole originalModule because some internal exported objects cause failures
// so we just unmock the necessary items.
// uncomment and use the following line if you need to check the contents of the module:
// const originalModule: typeof import('@stellar/stellar-sdk') = jest.requireActual('@stellar/stellar-sdk')
const originalModule = jest.requireActual('@stellar/stellar-sdk')
return {
Horizon: originalModule.Horizon,
Keypair: originalModule.Keypair,
Transaction: originalModule.Transaction,
FeeBumpTransaction: originalModule.FeeBumpTransaction,
xdr: originalModule.xdr,
authorizeEntry: jest.fn(),
}
})

const MOCKED_AUTHORIZE_ENTRY = authorizeEntry as jest.Mock

const MOCKED_SOROBAN_AUTH_ENTRY = {
credentials: jest.fn(),
rootInvocation: jest.fn(),
toXDR: jest.fn(),
} as xdr.SorobanAuthorizationEntry

const TESTNET_CONFIG = TestNet()

describe('DefaultAccountHandler', () => {
describe('Initialization', () => {
it('should initialize with just the networkConfig and generate a keypair', () => {
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG })
const spySecretKey = jest.mocked((dah as any).secretKey)

expect(spySecretKey).toBeDefined()
expect(dah.getPublicKey()).toBe(Keypair.fromSecret(spySecretKey as string).publicKey())
})

it('should initialize with a secret key', () => {
const secretKey = Keypair.random().secret()
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG, secretKey })

expect(dah.getPublicKey()).toBe(Keypair.fromSecret(secretKey).publicKey())
})

it('should sign a transaction with its secret key', () => {
const keypair = Keypair.random()
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG, secretKey: keypair.secret() })
const mockedXdrResult = 'Mocked XDR Result'
const mockedTx = {
sign: jest.fn().mockReturnValue('Signed'),
toXDR: jest.fn().mockReturnValue(mockedXdrResult),
} as unknown as Transaction
const spySign = jest.spyOn(mockedTx, 'sign')

const signedTx = dah.sign(mockedTx)

expect(signedTx).toBe(mockedXdrResult)
expect(spySign).toHaveBeenCalledExactlyOnceWith(keypair)
})

it('should sign a fee bummp transaction with its secret key', () => {
const keypair = Keypair.random()
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG, secretKey: keypair.secret() })
const mockedXdrResult = 'Mocked XDR Result'
const mockedTx = {
sign: jest.fn().mockReturnValue('Signed'),
toXDR: jest.fn().mockReturnValue(mockedXdrResult),
} as unknown as FeeBumpTransaction
const spySign = jest.spyOn(mockedTx, 'sign')

const signedTx = dah.sign(mockedTx)

expect(signedTx).toBe(mockedXdrResult)
expect(spySign).toHaveBeenCalledExactlyOnceWith(keypair)
})

it('should sign a soroban authorization entry with its secret key', async () => {
const keypair = Keypair.random()
MOCKED_AUTHORIZE_ENTRY.mockImplementationOnce(() => MOCKED_SOROBAN_AUTH_ENTRY)
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG, secretKey: keypair.secret() })

const signedEntry = await dah.signSorobanAuthEntry(
MOCKED_SOROBAN_AUTH_ENTRY,
123,
TESTNET_CONFIG.networkPassphrase
)

expect(signedEntry).toBe(MOCKED_SOROBAN_AUTH_ENTRY)
expect(MOCKED_AUTHORIZE_ENTRY).toHaveBeenCalledExactlyOnceWith(
MOCKED_SOROBAN_AUTH_ENTRY,
keypair,
123,
TESTNET_CONFIG.networkPassphrase
)
})
})

describe('Error Handling', () => {
beforeEach(() => {
jest.clearAllMocks()
})

it('should throw an error if the secret key provided in the constructor is invalid', () => {
const invalidSecretKey = 'Mocked Secret Key'

expect(() => {
new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG, secretKey: invalidSecretKey })
}).toThrow(DAHError.failedToLoadSecretKeyError(new Error('Mocked error')))
})

it('should throw an error if the public key cannot be derived from the current secret key', () => {
const invalidSecret = 'Mocked Secret Key'
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG })
jest.replaceProperty(dah as any, 'secretKey', invalidSecret)

expect(dah.getPublicKey).toThrow(DAHError.failedToLoadSecretKeyError(new Error('Mocked error')))
})

it('should throw an error if the transaction cannot be signed', () => {
const keypair = Keypair.random()
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG, secretKey: keypair.secret() })
const mockedTx = {
sign: jest.fn().mockImplementationOnce(() => {
throw new Error('Mocked error')
}),
toXDR: jest.fn(),
} as unknown as Transaction
const spySign = jest.spyOn(mockedTx, 'sign')

expect(() => {
dah.sign(mockedTx)
}).toThrow(DAHError.failedToSignTransactionError(new Error('Mocked error')))
expect(spySign).toHaveBeenCalledExactlyOnceWith(keypair)
})

it('should throw an error if the authorizeEntry cannot be signed', async () => {
const keypair = Keypair.random()
MOCKED_AUTHORIZE_ENTRY.mockImplementationOnce(() => {
throw new Error('Mocked error')
})
const dah = new DefaultAccountHandlerClient({ networkConfig: TESTNET_CONFIG, secretKey: keypair.secret() })

await expect(
dah.signSorobanAuthEntry(MOCKED_SOROBAN_AUTH_ENTRY, 123, TESTNET_CONFIG.networkPassphrase)
).rejects.toThrow(
DAHError.failedToSignAuthorizationEntryError(
new Error('Mocked error'),
'mocked auth entry xdr',
123,
TESTNET_CONFIG.networkPassphrase
)
)
})
})
})

This file was deleted.

Loading

0 comments on commit b7a18c3

Please sign in to comment.