mirror of
https://github.com/Permissionless-Software-Foundation/x402-base-facilitator.git
synced 2026-09-21 16:52:01 -07:00
344 lines
11 KiB
JavaScript
344 lines
11 KiB
JavaScript
/*
|
|
Unit tests for the Wallet Adapter library.
|
|
*/
|
|
|
|
// Global npm libraries
|
|
import { assert } from 'chai'
|
|
import sinon from 'sinon'
|
|
import BchWallet from 'minimal-slp-wallet'
|
|
import fs from 'fs'
|
|
|
|
// Local libraries
|
|
import WalletAdapter from '../../../src/adapters/wallet.adapter.js'
|
|
import { MockBchWallet } from '../mocks/adapters/wallet.js'
|
|
|
|
// Hack to get __dirname back.
|
|
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
|
|
import * as url from 'url'
|
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
|
|
// Global constants
|
|
const testWalletFile = `${__dirname.toString()}/test-wallet.json`
|
|
|
|
describe('#wallet', () => {
|
|
let uut
|
|
let sandbox
|
|
|
|
before(() => {
|
|
// Delete the test file if it exists.
|
|
try {
|
|
deleteFile(testWalletFile)
|
|
} catch (err) { }
|
|
})
|
|
|
|
beforeEach(() => {
|
|
uut = new WalletAdapter()
|
|
sandbox = sinon.createSandbox()
|
|
})
|
|
|
|
afterEach(() => sandbox.restore())
|
|
|
|
after(() => {
|
|
// Delete the test file if it exists.
|
|
try {
|
|
deleteFile(testWalletFile)
|
|
} catch (err) { }
|
|
})
|
|
|
|
describe('#_instanceWallet', () => {
|
|
it('should create a wallet given a mnemonic', async () => {
|
|
const mnemonic = 'wagon tray learn flat erase laugh lonely rug check captain jacket morning'
|
|
const result = await uut._instanceWallet(mnemonic)
|
|
// console.log('result: ', result)
|
|
assert.equal(result.walletInfo.mnemonic, mnemonic)
|
|
})
|
|
})
|
|
|
|
describe('#openWallet', () => {
|
|
it('should create a new wallet when wallet file does not exist', async () => {
|
|
// Mock dependencies
|
|
uut.BchWallet = MockBchWallet
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.walletFile = testWalletFile
|
|
const result = await uut.openWallet()
|
|
// console.log('result: ', result)
|
|
assert.property(result, 'mnemonic')
|
|
assert.property(result, 'privateKey')
|
|
assert.property(result, 'publicKey')
|
|
assert.property(result, 'cashAddress')
|
|
assert.property(result, 'address')
|
|
assert.property(result, 'slpAddress')
|
|
assert.property(result, 'legacyAddress')
|
|
assert.property(result, 'hdPath')
|
|
})
|
|
|
|
it('should open existing wallet file', async () => {
|
|
// This test case uses the file created in the previous test case.
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.walletFile = testWalletFile
|
|
const result = await uut.openWallet()
|
|
// console.log('result: ', result)
|
|
assert.property(result, 'mnemonic')
|
|
assert.property(result, 'privateKey')
|
|
assert.property(result, 'publicKey')
|
|
assert.property(result, 'cashAddress')
|
|
assert.property(result, 'address')
|
|
assert.property(result, 'slpAddress')
|
|
assert.property(result, 'legacyAddress')
|
|
assert.property(result, 'hdPath')
|
|
})
|
|
|
|
it('should catch and throw an error', async () => {
|
|
try {
|
|
// Force an error
|
|
uut.config.walletFile = ''
|
|
uut.BchWallet = () => {
|
|
}
|
|
await uut.openWallet()
|
|
// console.log('result: ', result)
|
|
assert.fail('Unexpected code path')
|
|
} catch (err) {
|
|
// console.log('err: ', err)
|
|
assert.include(err.message, 'this.BchWallet is not a constructor')
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('#instanceWalletWithoutInitialization', () => {
|
|
it('should create an instance of BchWallet', async () => {
|
|
// Create a mock wallet.
|
|
const mockWallet = new BchWallet()
|
|
await mockWallet.walletInfoPromise
|
|
sandbox.stub(mockWallet, 'initialize').resolves()
|
|
|
|
// Mock dependencies
|
|
sandbox.stub(uut, '_instanceWallet').resolves(mockWallet)
|
|
uut.config.authPass = 'fake-auth-pass'
|
|
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.config.walletFile = testWalletFile
|
|
const walletData = await uut.openWallet()
|
|
|
|
// console.log('walletData: ', walletData)
|
|
const result = await uut.instanceWalletWithoutInitialization(walletData)
|
|
// console.log('result: ', result)
|
|
|
|
assert.property(result, 'walletInfoPromise')
|
|
assert.property(result, 'walletInfo')
|
|
})
|
|
|
|
it('should catch and throw an error', async () => {
|
|
try {
|
|
// Force an error
|
|
sandbox.stub(uut, '_instanceWallet').rejects(new Error('test error'))
|
|
|
|
await uut.instanceWalletWithoutInitialization()
|
|
|
|
assert.fail('Unexpected code path')
|
|
} catch (err) {
|
|
// console.log('err: ', err)
|
|
assert.include(err.message, 'test error')
|
|
}
|
|
})
|
|
|
|
it('should create an instance of BchWallet using web2 infra', async () => {
|
|
// Create a mock wallet.
|
|
const mockWallet = new BchWallet()
|
|
await mockWallet.walletInfoPromise
|
|
sandbox.stub(mockWallet, 'initialize').resolves()
|
|
|
|
// Mock dependencies
|
|
sandbox.stub(uut, '_instanceWallet').resolves(mockWallet)
|
|
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.config.walletFile = testWalletFile
|
|
const walletData = await uut.openWallet()
|
|
// console.log('walletData: ', walletData)
|
|
|
|
// Force desired code path
|
|
uut.config.walletInterface = 'web2'
|
|
const result = await uut.instanceWalletWithoutInitialization(walletData)
|
|
|
|
// console.log('result: ', result)
|
|
assert.property(result, 'walletInfoPromise')
|
|
assert.property(result, 'walletInfo')
|
|
})
|
|
|
|
it('should generate wallet from mnemonic in config', async () => {
|
|
// Create a mock wallet.
|
|
const mockWallet = new BchWallet()
|
|
await mockWallet.walletInfoPromise
|
|
sandbox.stub(mockWallet, 'initialize').resolves()
|
|
|
|
// Mock dependencies
|
|
sandbox.stub(uut, '_instanceWallet').resolves(mockWallet)
|
|
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.config.walletFile = testWalletFile
|
|
const walletData = await uut.openWallet()
|
|
// console.log('walletData: ', walletData)
|
|
|
|
const originalConfig = uut.config.mnemonic
|
|
uut.config.mnemonic = walletData.mnemonic
|
|
|
|
const result = await uut.instanceWalletWithoutInitialization({})
|
|
// console.log('result: ', result)
|
|
|
|
uut.config.mnemonic = originalConfig
|
|
|
|
assert.property(result, 'walletInfoPromise')
|
|
assert.property(result, 'walletInfo')
|
|
})
|
|
})
|
|
|
|
describe('#instanceWallet', () => {
|
|
it('should create an instance of BchWallet', async () => {
|
|
// Create a mock wallet.
|
|
const mockWallet = new BchWallet()
|
|
await mockWallet.walletInfoPromise
|
|
sandbox.stub(mockWallet, 'initialize').resolves()
|
|
|
|
// Mock dependencies
|
|
sandbox.stub(uut, '_instanceWallet').resolves(mockWallet)
|
|
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.WALLET_FILE = testWalletFile
|
|
const walletData = await uut.openWallet()
|
|
// console.log('walletData: ', walletData)
|
|
const result = await uut.instanceWallet(walletData)
|
|
// console.log('result: ', result)
|
|
|
|
assert.property(result, 'walletInfoPromise')
|
|
assert.property(result, 'walletInfo')
|
|
})
|
|
|
|
it('should catch and throw an error', async () => {
|
|
try {
|
|
// Force an error
|
|
sandbox.stub(uut, 'instanceWalletWithoutInitialization').rejects(new Error('test error'))
|
|
|
|
await uut.instanceWallet()
|
|
assert.fail('Unexpected code path')
|
|
} catch (err) {
|
|
// console.log('err: ', err)
|
|
assert.include(err.message, 'test error')
|
|
}
|
|
})
|
|
|
|
it('should create an instance of BchWallet using web2 infra', async () => {
|
|
// Create a mock wallet.
|
|
const mockWallet = new BchWallet()
|
|
await mockWallet.walletInfoPromise
|
|
sandbox.stub(mockWallet, 'initialize').resolves()
|
|
|
|
// Mock dependencies
|
|
sandbox.stub(uut, '_instanceWallet').resolves(mockWallet)
|
|
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.WALLET_FILE = testWalletFile
|
|
const walletData = await uut.openWallet()
|
|
// console.log('walletData: ', walletData)
|
|
|
|
// Force desired code path
|
|
uut.config.useFullStackCash = true
|
|
const result = await uut.instanceWallet(walletData)
|
|
// console.log('result: ', result)
|
|
|
|
assert.property(result, 'walletInfoPromise')
|
|
assert.property(result, 'walletInfo')
|
|
})
|
|
})
|
|
|
|
describe('#incrementNextAddress', () => {
|
|
it('should increment the nextAddress property', async () => {
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.WALLET_FILE = testWalletFile
|
|
// mock instance of minimal-slp-wallet
|
|
uut.bchWallet = new MockBchWallet()
|
|
const result = await uut.incrementNextAddress()
|
|
assert.equal(result, 2)
|
|
})
|
|
|
|
it('should catch and throw an error', async () => {
|
|
try {
|
|
// Force an error
|
|
sandbox.stub(uut, 'openWallet').rejects(new Error('test error'))
|
|
await uut.incrementNextAddress()
|
|
assert.fail('Unexpected code path')
|
|
} catch (err) {
|
|
assert.include(err.message, 'test error')
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('#getKeyPair', () => {
|
|
it('should return an object with a key pair', async () => {
|
|
// Ensure we open the test file, not the production wallet file.
|
|
uut.WALLET_FILE = testWalletFile
|
|
// mock instance of minimal-slp-wallet
|
|
uut.bchWallet = new MockBchWallet()
|
|
const result = await uut.getKeyPair()
|
|
// console.log('result: ', result)
|
|
assert.property(result, 'cashAddress')
|
|
assert.property(result, 'wif')
|
|
assert.property(result, 'hdIndex')
|
|
})
|
|
|
|
it('should catch and throw an error', async () => {
|
|
try {
|
|
// Force an error
|
|
sandbox
|
|
.stub(uut, 'incrementNextAddress')
|
|
.rejects(new Error('test error'))
|
|
await uut.getKeyPair()
|
|
assert.fail('Unexpected code path')
|
|
} catch (err) {
|
|
assert.include(err.message, 'test error')
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('#optimize', () => {
|
|
it('should call the wallet optimize function', async () => {
|
|
// mock instance of minimal-slp-wallet
|
|
uut.bchWallet = new MockBchWallet()
|
|
sandbox.stub(uut.bchWallet, 'optimize').resolves({ bchUtxoCnt: 10 })
|
|
const result = await uut.optimize()
|
|
assert.equal(result, true)
|
|
})
|
|
})
|
|
|
|
describe('#getBalance', () => {
|
|
it('should get the balance for the wallet', async () => {
|
|
// mock instance of minimal-slp-wallet
|
|
uut.bchWallet = new MockBchWallet()
|
|
// Mock dependencies and force desired code path
|
|
sandbox.stub(uut.bchWallet, 'getBalance').resolves(41012)
|
|
sandbox.stub(uut.bchWallet, 'listTokens').resolves([{
|
|
tokenId: '38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0',
|
|
ticker: 'PSF',
|
|
name: 'Permissionless Software Foundation',
|
|
decimals: 8,
|
|
tokenType: 1,
|
|
url: 'psfoundation.cash',
|
|
qty: 2
|
|
}])
|
|
const result = await uut.getBalance()
|
|
// console.log('result: ', result)
|
|
// Assert the expected properties exist and have the expected values.
|
|
assert.equal(result.satBalance, 41012)
|
|
assert.equal(result.psfBalance, 2)
|
|
assert.equal(result.success, true)
|
|
})
|
|
})
|
|
})
|
|
|
|
const deleteFile = (filepath) => {
|
|
try {
|
|
// Delete state if exist
|
|
fs.unlinkSync(filepath)
|
|
} catch (err) {
|
|
// console.error('Error trying to delete file: ', err)
|
|
}
|
|
}
|