Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add fees and coin selection #159

Draft
wants to merge 42 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
54dac3a
Merge branch 'cashubtc:main' into amt_preference_fixes
lollerfirst Jun 18, 2024
ec76cc3
getPreferences checks against keyset amounts, not necessarily powers …
lollerfirst Jun 18, 2024
a5e4cd2
remove splitAmount fix for "filling up the rest" behaviour
lollerfirst Jun 18, 2024
4d51bf9
sendPreference, keepPreference
lollerfirst Jun 18, 2024
bd00ff6
splitAmount: split is now based on key amounts, not powers of 2.
lollerfirst Jun 18, 2024
f7f37a6
fix for integration test
lollerfirst Jun 19, 2024
63b2c1e
primary order is ascending amounts
lollerfirst Jun 20, 2024
4766e90
npm run format
lollerfirst Jun 20, 2024
b858878
Merge remote-tracking branch 'upstream/staging' into amt_preference_f…
lollerfirst Jun 26, 2024
9a0e589
updated tests
Egge21M Jun 28, 2024
6ed41a9
added cbor-x
Egge21M Jun 28, 2024
1060428
added tokenv4 parsing / removed depracated token
Egge21M Jun 28, 2024
b5ec29b
remove cbor dependency
Egge21M Jun 30, 2024
a34c439
added byte id and C
Egge21M Jul 1, 2024
7f23bf2
added testcases and multi token
Egge21M Jul 1, 2024
da1c603
specified return type
Egge21M Jul 1, 2024
c68de1a
cleanup rebase
Egge21M Jul 4, 2024
c91c27e
added cbor test cases
Egge21M Jul 18, 2024
79cefe5
fixed 16 bit float parsing
Egge21M Jul 18, 2024
b2f70a5
wip
callebtc Jul 22, 2024
0197df4
tests working again
callebtc Jul 22, 2024
13dfedd
Merge remote-tracking branch 'upstream/development' into amt_preferen…
lollerfirst Jul 25, 2024
64236c3
wip: working
callebtc Jul 25, 2024
003c5fd
cleanup
callebtc Jul 25, 2024
59417ad
refactor
callebtc Jul 26, 2024
65f5c8c
wip
callebtc Jul 26, 2024
07db2ef
owrks
callebtc Jul 26, 2024
865d93c
npm run format
callebtc Jul 26, 2024
9bf559a
Merge branch 'amt_preference_fixes-patch' into fees-and-coinselection
callebtc Jul 26, 2024
69e1fcb
merge with preferences branch
callebtc Jul 28, 2024
b8e90a3
use latest nutshell docker image for integration tests
callebtc Jul 28, 2024
8414ae2
npm run format
callebtc Jul 28, 2024
97686ce
Merge branch 'ci-nutshell-latest' into fees-and-coinselection
callebtc Jul 28, 2024
6aa0553
fix test
callebtc Jul 28, 2024
29a2915
fix test script
callebtc Jul 28, 2024
5be7715
wip
callebtc Jul 29, 2024
175373a
wip: output selection
callebtc Jul 30, 2024
d32e697
tmp
callebtc Aug 27, 2024
013590c
working agian
callebtc Oct 1, 2024
cbb98a1
Merge branch 'development' into fees-and-coinselection
callebtc Oct 1, 2024
2a5d834
npm run format
callebtc Oct 1, 2024
7e72950
remove empty file
callebtc Oct 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
owrks
  • Loading branch information
callebtc committed Jul 26, 2024
commit 07db2ef4570d190af917dbee49c95f927d1da665
8 changes: 6 additions & 2 deletions src/CashuWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import {
import {
bytesToNumber,
getDecodedToken,
splitAmount
splitAmount,
deprecatedPreferenceToOutputAmounts
} from './utils.js';
import { validateMnemonic } from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
Expand Down Expand Up @@ -132,6 +133,7 @@ class CashuWallet {
privkey?: string;
}
): Promise<Array<Proof>> {
if (options?.preference) options.outputAmounts = deprecatedPreferenceToOutputAmounts(options.preference);
try {
if (typeof token === 'string') {
token = getDecodedToken(token);
Expand Down Expand Up @@ -170,6 +172,7 @@ class CashuWallet {
privkey?: string;
}
): Promise<Array<Proof>> {
if (options?.preference) options.outputAmounts = deprecatedPreferenceToOutputAmounts(options.preference);
const proofs: Array<Proof> = [];
try {
const amount = tokenEntry.proofs.reduce((total, curr) => total + curr.amount, 0);
Expand Down Expand Up @@ -222,6 +225,7 @@ class CashuWallet {
keysetId?: string;
}
): Promise<SendResponse> {
if (options?.preference) options.outputAmounts = deprecatedPreferenceToOutputAmounts(options.preference);
const keyset = await this.getKeys(options?.keysetId);
let amountAvailable = 0;
const proofsToSend: Array<Proof> = [];
Expand Down Expand Up @@ -361,7 +365,6 @@ class CashuWallet {
* @param amount amount to request
* @param quote ID of mint quote
* @param options.keysetId? optionally set keysetId for blank outputs for returned change.
* @deprecated
* @param preference? Deprecated. Use `outputAmounts` instead. Optional preference for splitting proofs into specific amounts.
* @param outputAmounts? optionally specify the output's amounts to keep and to send.
* @param counter? optionally set counter to derive secret deterministically. CashuWallet class must be initialized with seed phrase to take effect
Expand All @@ -379,6 +382,7 @@ class CashuWallet {
pubkey?: string;
}
): Promise<{ proofs: Array<Proof> }> {
if (options?.preference) options.outputAmounts = deprecatedPreferenceToOutputAmounts(options.preference);
const keyset = await this.getKeys(options?.keysetId);
const { blindedMessages, secrets, rs } = this.createRandomBlindedMessages(
amount,
Expand Down
25 changes: 15 additions & 10 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { encodeBase64ToJson, encodeBase64toUint8, encodeJsonToBase64 } from './base64.js';
import { AmountPreference, Keys, Proof, Token, TokenEntry, TokenV2 } from './model/types/index.js';
import { AmountPreference, Keys, OutputAmounts, Proof, Token, TokenEntry, TokenV2 } from './model/types/index.js';
import { TOKEN_PREFIX, TOKEN_VERSION } from './utils/Constants.js';
import { bytesToHex, hexToBytes } from '@noble/curves/abstract/utils';
import { sha256 } from '@noble/hashes/sha256';
Expand All @@ -13,6 +13,9 @@ function splitAmount(
): Array<number> {
const chunks: Array<number> = [];
if (split) {
if (split.reduce((a, b) => a + b, 0) > value) {
throw new Error('Split amount is greater than the value');
}
chunks.push(...getPreference(value, keyset, split));
value =
value -
Expand Down Expand Up @@ -45,23 +48,24 @@ function getPreference(
split: Array<number>
): Array<number> {
const chunks: Array<number> = [];
let accumulator = 0;
split.forEach((splitAmount) => {
if (!hasCorrespondingKey(splitAmount, keyset)) {
throw new Error('Provided amount preferences do not match the amounts of the mint keyset.');
}
const count = split.filter(value => value === splitAmount).length;
for (let i = 1; i <= count; i++) {
accumulator += splitAmount;
if (accumulator > amount) {
return;
}
chunks.push(splitAmount);
}
chunks.push(splitAmount);
});
return chunks;
}

function deprecatedPreferenceToOutputAmounts(preference?: Array<AmountPreference>): OutputAmounts {
const sendAmounts: Array<number> = [];
preference?.forEach(({ count, amount }) => {
for (let i = 0; i < count; i++) {
sendAmounts.push(amount);
}
});
return { sendAmounts };
}
function bytesToNumber(bytes: Uint8Array): bigint {
return hexToNumber(bytesToHex(bytes));
}
Expand Down Expand Up @@ -189,4 +193,5 @@ export {
getEncodedToken,
hexToNumber,
splitAmount,
deprecatedPreferenceToOutputAmounts,
};
10 changes: 9 additions & 1 deletion test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,19 @@ describe('test split custom amounts ', () => {
const chunks = utils.splitAmount(10, keys, tenToOneAndTwo);
expect(chunks).toStrictEqual([1, 1, 2, 2, 2, 2]);
});
const fiveTwelve = [512, 512];
test('testing amount 12', async () => {
const chunks = utils.splitAmount(12, keys, tenToOneAndTwo);
expect(chunks).toStrictEqual([1, 1, 2, 2, 2, 2, 2]);
});
const fiveTwelve = [512];
test('testing amount 518', async () => {
const chunks = utils.splitAmount(518, keys, fiveTwelve, 'desc');
expect(chunks).toStrictEqual([512, 4, 2]);
});
const tooMuch = [512, 512];
test('testing amount 512 but split too much', async () => {
expect(() => utils.splitAmount(512, keys, tooMuch)).toThrowError();
});
const illegal = [3, 3];
test('testing non pow2', async () => {
expect(() => utils.splitAmount(6, keys, illegal)).toThrowError();
Expand Down
Loading