Skip to content

Commit 8592357

Browse files
Merge pull request #8578 from BitGo/feat/SI-287-flrp-create-paired-wallet
feat(sdk-coin-flrp): add createPairedWallet method to Flrp
2 parents 3a61f6a + eeae274 commit 8592357

4 files changed

Lines changed: 115 additions & 2 deletions

File tree

modules/sdk-coin-flrp/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
},
4545
"devDependencies": {
4646
"@bitgo/sdk-api": "^1.81.1",
47-
"@bitgo/sdk-test": "^9.1.46"
47+
"@bitgo/sdk-test": "^9.1.46",
48+
"nock": "^13.3.1"
4849
},
4950
"dependencies": {
5051
"@bitgo/public-types": "6.22.0",

modules/sdk-coin-flrp/src/flrp.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
} from '@bitgo/sdk-core';
2323
import * as FlrpLib from './lib';
2424
import {
25+
CreatePairedWalletParams,
26+
CreatePairedWalletResponse,
2527
FlrpEntry,
2628
FlrpExplainTransactionOptions,
2729
FlrpSignTransactionOptions,
@@ -444,4 +446,12 @@ export class Flrp extends BaseCoin {
444446
auditDecryptedKey(params: AuditDecryptedKeyParams): void {
445447
throw new MethodNotImplementedError();
446448
}
449+
450+
async createPairedWallet(params: CreatePairedWalletParams): Promise<CreatePairedWalletResponse> {
451+
const { walletId, label } = params;
452+
return this.bitgo
453+
.post(this.url(`/wallet/${walletId}/create-paired-wallet`))
454+
.send(label ? { label } : {})
455+
.result();
456+
}
447457
}

modules/sdk-coin-flrp/src/lib/iface.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,34 @@ export interface ExportEVMOptions {
176176
threshold: number;
177177
locktime: bigint;
178178
}
179+
180+
/**
181+
* Parameters for creating a paired FLR C-chain wallet from an FLR P-chain wallet.
182+
*/
183+
export interface CreatePairedWalletParams {
184+
/** The ID of the source FLRP (FLR P-chain) MPC wallet. */
185+
walletId: string;
186+
/** Optional label for the new FLR C-chain wallet. */
187+
label?: string;
188+
}
189+
190+
/**
191+
* Response from the create-paired-wallet endpoint.
192+
*/
193+
export interface CreatePairedWalletResponse {
194+
id: string;
195+
coin: string;
196+
label: string;
197+
keys: string[];
198+
keySignatures: Record<string, string>;
199+
m: number;
200+
n: number;
201+
type: string;
202+
multisigType: string;
203+
coinSpecific: {
204+
pairedWalletId?: string;
205+
baseAddress?: string;
206+
[key: string]: unknown;
207+
};
208+
[key: string]: unknown;
209+
}

modules/sdk-coin-flrp/test/unit/flrp.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ import {
1414
MULTISIG_DELEGATION_PARAMS,
1515
MPC_DELEGATION_UNSIGNED_TX_HEX,
1616
} from '../resources/transactionData/multisigDelegationTx';
17-
import { HalfSignedAccountTransaction, TransactionType, MPCAlgorithm } from '@bitgo/sdk-core';
17+
import { HalfSignedAccountTransaction, TransactionType, MPCAlgorithm, common } from '@bitgo/sdk-core';
1818
import { secp256k1 } from '@flarenetwork/flarejs';
1919
import { FlrpContext } from '@bitgo/public-types';
2020
import assert from 'assert';
21+
import nock from 'nock';
22+
import { CreatePairedWalletResponse } from '../../src/lib/iface';
2123

2224
describe('Flrp test cases', function () {
2325
const coinName = 'flrp';
@@ -1086,4 +1088,73 @@ describe('Flrp test cases', function () {
10861088
});
10871089
});
10881090
});
1091+
1092+
describe('createPairedWallet', function () {
1093+
const walletId = 'abc123def456abc123def456abc123de';
1094+
1095+
afterEach(function () {
1096+
nock.cleanAll();
1097+
});
1098+
1099+
it('should POST to create-paired-wallet and return new wallet', async function () {
1100+
const bgUrl = common.Environments[bitgo.getEnv()].uri;
1101+
const expectedResponse: CreatePairedWalletResponse = {
1102+
id: 'newwalletid000000000000000000001',
1103+
coin: 'tflr',
1104+
label: 'My FLR C Wallet',
1105+
keys: ['key1', 'key2', 'key3'],
1106+
keySignatures: { backupPub: 'sig1', bitgoPub: 'sig2' },
1107+
m: 2,
1108+
n: 3,
1109+
type: 'hot',
1110+
multisigType: 'tss',
1111+
coinSpecific: {
1112+
pairedWalletId: walletId,
1113+
baseAddress: '0x627306090abaB3A6e1400e9345bC60c78a8BEf57',
1114+
},
1115+
};
1116+
1117+
nock(bgUrl)
1118+
.post(`/api/v2/tflrp/wallet/${walletId}/create-paired-wallet`, { label: 'My FLR C Wallet' })
1119+
.reply(200, expectedResponse);
1120+
1121+
const result = await basecoin.createPairedWallet({ walletId, label: 'My FLR C Wallet' });
1122+
result.should.deepEqual(expectedResponse);
1123+
result.coin.should.equal('tflr');
1124+
result.coinSpecific.pairedWalletId.should.equal(walletId);
1125+
});
1126+
1127+
it('should POST without body when label is not provided', async function () {
1128+
const bgUrl = common.Environments[bitgo.getEnv()].uri;
1129+
const expectedResponse: CreatePairedWalletResponse = {
1130+
id: 'newwalletid000000000000000000002',
1131+
coin: 'tflr',
1132+
label: 'FLR C wallet (from tflrp wallet abc123def456abc123def456abc123de)',
1133+
keys: ['key1', 'key2', 'key3'],
1134+
keySignatures: {},
1135+
m: 2,
1136+
n: 3,
1137+
type: 'hot',
1138+
multisigType: 'tss',
1139+
coinSpecific: { pairedWalletId: walletId },
1140+
};
1141+
1142+
nock(bgUrl).post(`/api/v2/tflrp/wallet/${walletId}/create-paired-wallet`, {}).reply(200, expectedResponse);
1143+
1144+
const result = await basecoin.createPairedWallet({ walletId });
1145+
result.should.deepEqual(expectedResponse);
1146+
});
1147+
1148+
it('should propagate HTTP errors from the server', async function () {
1149+
const bgUrl = common.Environments[bitgo.getEnv()].uri;
1150+
1151+
nock(bgUrl)
1152+
.post(`/api/v2/tflrp/wallet/${walletId}/create-paired-wallet`)
1153+
.reply(400, { error: 'Source FLR P wallet is not MPC (multisigType: onchain)' });
1154+
1155+
await basecoin
1156+
.createPairedWallet({ walletId })
1157+
.should.be.rejectedWith('Source FLR P wallet is not MPC (multisigType: onchain)');
1158+
});
1159+
});
10891160
});

0 commit comments

Comments
 (0)