Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions modules/sdk-coin-flrp/src/flrp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
} from '@bitgo/sdk-core';
import * as FlrpLib from './lib';
import {
CreatePairedWalletParams,
CreatePairedWalletResponse,
FlrpEntry,
FlrpExplainTransactionOptions,
FlrpSignTransactionOptions,
Expand Down Expand Up @@ -436,4 +438,12 @@ export class Flrp extends BaseCoin {
auditDecryptedKey(params: AuditDecryptedKeyParams): void {
throw new MethodNotImplementedError();
}

async createPairedWallet(params: CreatePairedWalletParams): Promise<CreatePairedWalletResponse> {
const { walletId, label } = params;
return this.bitgo
.post(this.url(`/wallet/${walletId}/create-paired-wallet`))
.send(label ? { label } : {})
.result();
}
}
31 changes: 31 additions & 0 deletions modules/sdk-coin-flrp/src/lib/iface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,34 @@ export interface ExportEVMOptions {
threshold: number;
locktime: bigint;
}

/**
* Parameters for creating a paired FLR C-chain wallet from an FLR P-chain wallet.
*/
export interface CreatePairedWalletParams {
/** The ID of the source FLRP (FLR P-chain) MPC wallet. */
walletId: string;
/** Optional label for the new FLR C-chain wallet. */
label?: string;
}

/**
* Response from the create-paired-wallet endpoint.
*/
export interface CreatePairedWalletResponse {
id: string;
coin: string;
label: string;
keys: string[];
keySignatures: Record<string, string>;
m: number;
n: number;
type: string;
multisigType: string;
coinSpecific: {
pairedWalletId?: string;
baseAddress?: string;
[key: string]: unknown;
};
[key: string]: unknown;
}
73 changes: 72 additions & 1 deletion modules/sdk-coin-flrp/test/unit/flrp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import { EXPORT_IN_C } from '../resources/transactionData/exportInC';
import { EXPORT_IN_P } from '../resources/transactionData/exportInP';
import { IMPORT_IN_P } from '../resources/transactionData/importInP';
import { IMPORT_IN_C } from '../resources/transactionData/importInC';
import { HalfSignedAccountTransaction, TransactionType, MPCAlgorithm } from '@bitgo/sdk-core';
import { HalfSignedAccountTransaction, TransactionType, MPCAlgorithm, common } from '@bitgo/sdk-core';
import { secp256k1 } from '@flarenetwork/flarejs';
import { FlrpContext } from '@bitgo/public-types';
import assert from 'assert';
import nock from 'nock';
import { CreatePairedWalletResponse } from '../../src/lib/iface';

describe('Flrp test cases', function () {
const coinName = 'flrp';
Expand Down Expand Up @@ -960,4 +962,73 @@ describe('Flrp test cases', function () {
});
});
});

describe('createPairedWallet', function () {
const walletId = 'abc123def456abc123def456abc123de';

afterEach(function () {
nock.cleanAll();
});

it('should POST to create-paired-wallet and return new wallet', async function () {
const bgUrl = common.Environments[bitgo.getEnv()].uri;
const expectedResponse: CreatePairedWalletResponse = {
id: 'newwalletid000000000000000000001',
coin: 'tflr',
label: 'My FLR C Wallet',
keys: ['key1', 'key2', 'key3'],
keySignatures: { backupPub: 'sig1', bitgoPub: 'sig2' },
m: 2,
n: 3,
type: 'hot',
multisigType: 'tss',
coinSpecific: {
pairedWalletId: walletId,
baseAddress: '0x627306090abaB3A6e1400e9345bC60c78a8BEf57',
},
};

nock(bgUrl)
.post(`/api/v2/tflrp/wallet/${walletId}/create-paired-wallet`, { label: 'My FLR C Wallet' })
.reply(200, expectedResponse);

const result = await basecoin.createPairedWallet({ walletId, label: 'My FLR C Wallet' });
result.should.deepEqual(expectedResponse);
result.coin.should.equal('tflr');
result.coinSpecific.pairedWalletId.should.equal(walletId);
});

it('should POST without body when label is not provided', async function () {
const bgUrl = common.Environments[bitgo.getEnv()].uri;
const expectedResponse: CreatePairedWalletResponse = {
id: 'newwalletid000000000000000000002',
coin: 'tflr',
label: 'FLR C wallet (from tflrp wallet abc123def456abc123def456abc123de)',
keys: ['key1', 'key2', 'key3'],
keySignatures: {},
m: 2,
n: 3,
type: 'hot',
multisigType: 'tss',
coinSpecific: { pairedWalletId: walletId },
};

nock(bgUrl).post(`/api/v2/tflrp/wallet/${walletId}/create-paired-wallet`, {}).reply(200, expectedResponse);

const result = await basecoin.createPairedWallet({ walletId });
result.should.deepEqual(expectedResponse);
});

it('should propagate HTTP errors from the server', async function () {
const bgUrl = common.Environments[bitgo.getEnv()].uri;

nock(bgUrl)
.post(`/api/v2/tflrp/wallet/${walletId}/create-paired-wallet`)
.reply(400, { error: 'Source FLR P wallet is not MPC (multisigType: onchain)' });

await basecoin
.createPairedWallet({ walletId })
.should.be.rejectedWith('Source FLR P wallet is not MPC (multisigType: onchain)');
});
});
});
Loading