Skip to content

Commit

Permalink
feat(sdk-core): reserve unspents from the SDK
Browse files Browse the repository at this point in the history
Manage unspent reservations with the SDK

BTC-1504
  • Loading branch information
davidkaplanbitgo committed Sep 24, 2024
1 parent b83f6f1 commit 42ffe16
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
43 changes: 43 additions & 0 deletions modules/bitgo/test/v2/unit/unspents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,47 @@ describe('Verify string type is used for value of unspent', function () {
buildScope.done();
});
});

describe('Unspent Reservations', function () {
after(nock.cleanAll);

it('should only pass through the whitelisted properties', async function () {
const unspentIds = ['test-test'];
const expireTime = 'boogie';

// Create
const createScope = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.id()}/reservedunspents`, { unspentIds, expireTime })
.reply(200, {});
await wallet.manageUnspentReservations({
create: { unspentIds, expireTime, dontIncludeThis: 'this' } as unknown as {
unspentIds: string[];
expireTime: string;
},
});

// Modify
const modifyScope = nock(bgUrl)
.put(`/api/v2/wallet/${wallet.id()}/reservedunspents`, { unspentIds, changes: { expireTime } })
.reply(200, {});
await wallet.manageUnspentReservations({
modify: { unspentIds, changes: { expireTime }, dontIncludeThis: 'this' } as unknown as {
unspentIds: string[];
changes: { expireTime: string };
},
});

// Delete
const deleteScope = nock(bgUrl)
.delete(`/api/v2/wallet/${wallet.id()}/reservedunspents?id=test-test`)
.reply(200, {});
await wallet.manageUnspentReservations({
delete: { id: unspentIds[0], dontIncludeThis: 'this' } as unknown as { id: string },
});

createScope.done();
modifyScope.done();
deleteScope.done();
});
});
});
16 changes: 16 additions & 0 deletions modules/sdk-core/src/bitgo/wallet/iWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,22 @@ export interface UnspentsOptions extends PaginationOptions {
chains?: number[];
}

export interface ManageUnspentReservationOptions {
create?: {
unspentIds: string[];
expireTime: string;
};
modify?: {
unspentIds: string[];
changes: {
expireTime: string;
};
};
delete?: {
id: string;
};
}

export interface ConsolidateUnspentsOptions extends WalletSignTransactionOptions {
walletPassphrase?: string;
xprv?: string;
Expand Down
29 changes: 29 additions & 0 deletions modules/sdk-core/src/bitgo/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import {
CreateBulkWalletShareListResponse,
SharedKeyChain,
BulkWalletShareKeychain,
ManageUnspentReservationOptions,
} from './iWallet';
import { StakingWallet } from '../staking';
import { Lightning } from '../lightning/custodial';
Expand Down Expand Up @@ -740,6 +741,34 @@ export class Wallet implements IWallet {
return Array.isArray(buildResponse) ? response : response[0];
}

/**
* Manage the unspent reservations on the wallet
*
* @param params.create - create a new reservation
* @param params.modify - modify an existing reservation
* @param params.delete - delete an existing reservation
*/
async manageUnspentReservations(
params: ManageUnspentReservationOptions
): Promise<{ unspents: { id: string; walletId: string; expireTime: string; userId?: string }[] }> {
const filteredParams = _.pick(params, ['create', 'modify', 'delete']);
this.bitgo.setRequestTracer(new RequestTracer());
// The URL cannot contain the coinName, so we remove it from the URL
const url = this.url(`/reservedunspents`).replace(`/${this.baseCoin.getChain()}`, '');
if (filteredParams.create) {
const filteredCreateParams = _.pick(params.create, ['unspentIds', 'expireTime']);
return this.bitgo.post(url).send(filteredCreateParams).result();
} else if (filteredParams.modify) {
const filteredModifyParams = _.pick(params.modify, ['unspentIds', 'changes']);
return this.bitgo.put(url).send(filteredModifyParams).result();
} else if (filteredParams.delete) {
const filteredDeleteParams = _.pick(params.delete, ['id']);
return this.bitgo.del(url).query(filteredDeleteParams).result();
} else {
throw new Error('Did not detect a creation, modification, or deletion request.');
}
}

/**
* Consolidate unspents on a wallet
*
Expand Down

0 comments on commit 42ffe16

Please sign in to comment.