emblem-vault-sdk 2.3.6 → 3.0.0-experimental
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.traces/blockchain-provider-abstraction-plan.md +302 -0
- package/.traces/notes.md +43 -0
- package/.traces/readme-verification-trace.md +988 -0
- package/.traces/test-migration-status.md +227 -0
- package/.traces/tests-consolidated-trace.md +667 -0
- package/dist/abi/abi.json +53 -0
- package/dist/bundle.js +21602 -17419
- package/dist/clients/emblemVaultSolanaWalletClient.d.ts +74 -0
- package/dist/clients/emblemVaultSolanaWalletClient.js +149 -0
- package/dist/clients/emblemVaultSolanaWalletClient.js.map +1 -0
- package/dist/clients/emblemVaultWalletClient.d.ts +52 -0
- package/dist/clients/emblemVaultWalletClient.js +110 -0
- package/dist/clients/emblemVaultWalletClient.js.map +1 -0
- package/dist/derive.js +7 -0
- package/dist/derive.js.map +1 -0
- package/dist/index.js +319 -114
- package/dist/index.js.map +1 -0
- package/dist/providers/ProviderManager.d.ts +57 -0
- package/dist/providers/ProviderManager.js +283 -0
- package/dist/providers/ProviderManager.js.map +1 -0
- package/dist/providers.d.ts +101 -0
- package/dist/providers.js +96 -0
- package/dist/providers.js.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.js +61 -58
- package/dist/utils.js.map +1 -0
- package/docs/bundle.js +21602 -17419
- package/docs/index.html +150 -13
- package/docs/local.html +385 -0
- package/docs/steps.html +420 -53
- package/package.json +22 -13
- package/readme.md +795 -21
- package/src/abi/abi.json +54 -1
- package/src/clients/emblemVaultSolanaWalletClient.ts +257 -0
- package/src/clients/emblemVaultWalletClient.ts +159 -0
- package/src/derive.ts +5 -5
- package/src/index.ts +320 -102
- package/src/providers/ProviderManager.ts +254 -0
- package/src/providers.ts +163 -0
- package/src/types.ts +50 -0
- package/src/utils.ts +63 -62
- package/test/.mocharc.js +8 -0
- package/test/README.md +212 -0
- package/test/fixtures/ethscriptions/balance-with-native-first.json +24 -0
- package/test/fixtures/ethscriptions/balance-with-native.json +23 -0
- package/test/fixtures/ethscriptions/balance.json +18 -0
- package/test/helpers/sdkLoader.js +88 -0
- package/test/helpers/setup.js +55 -0
- package/test/integration/ApiOperations.spec.js +102 -0
- package/test/integration/VaultAI.spec.js +57 -0
- package/test/integration/VaultCreation.spec.js +95 -0
- package/test/mocks.js +127 -0
- package/test/tsconfig.json +25 -0
- package/test/unit/AllowedBells.spec.js +53 -0
- package/test/unit/AllowedBitcoinDeGods.spec.js +53 -0
- package/test/unit/AllowedBitcoinOrdinals.spec.js +46 -0
- package/test/unit/AllowedCounterparty.spec.js +66 -0
- package/test/unit/AllowedCursedOrdinals.spec.js +68 -0
- package/test/unit/AllowedEmbells.spec.js +11 -0
- package/test/unit/AllowedEmbels.spec.js +11 -0
- package/test/unit/AllowedEmblemOpen.spec.js +20 -0
- package/test/unit/AllowedEthscriptions.spec.js +53 -0
- package/test/unit/AllowedHardcodedNfts.spec.js +77 -0
- package/test/unit/AllowedNamecoin.spec.js +33 -0
- package/test/unit/AllowedOrdi.spec.js +46 -0
- package/test/unit/AllowedOxbt.spec.js +46 -0
- package/test/unit/AllowedProjectCollection.spec.js +51 -0
- package/test/unit/AllowedProtocolCollection.spec.js +44 -0
- package/test/unit/AllowedStamps.spec.js +78 -0
- package/test/unit/DarkfarmsMetadata.spec.js +10 -0
- package/test/unit/EmblemVaultSdk.spec.js +188 -0
- package/test/unit/Providers.spec.js +290 -0
- package/test/unit/ResourceMonitor.spec.js +111 -0
- package/test/unit/SDKMemoryLeaks.spec.js +176 -0
- package/test/unit/Signing.spec.js +321 -0
- package/test/unit/VaultAI.spec.js +140 -0
- package/test/unit/clients/EmblemVaultSolanaWalletClient.spec.js +296 -0
- package/test/unit/clients/EmblemVaultWalletClient.spec.js +246 -0
- package/test/utils/ResourceMonitor.js +169 -0
- package/test/windsurf-rules.md +68 -0
- package/tsconfig.json +7 -3
- package/types/derive.d.ts +0 -5
- package/types/index.d.ts +152 -32
- package/types/types.d.ts +43 -0
- package/types/utils.d.ts +7 -1
- package/dist/abi/quote.js +0 -29
- package/dist/abi/quote.json +0 -26
- package/jest.config.js +0 -6
- package/tests/AllowedBells.test.ts +0 -53
- package/tests/AllowedBitcoinDeGods.test.ts +0 -53
- package/tests/AllowedBitcoinOrdinals.test.ts +0 -46
- package/tests/AllowedCounterparty.test.ts +0 -45
- package/tests/AllowedCursedOrdinals.test.ts +0 -68
- package/tests/AllowedEmbells.test.ts +0 -12
- package/tests/AllowedEmbels.test.ts +0 -16
- package/tests/AllowedEmblemOpen.test.ts +0 -20
- package/tests/AllowedEthscriptions.test.ts +0 -39
- package/tests/AllowedHardcodedNfts.test.ts +0 -78
- package/tests/AllowedNamecoin.test.ts +0 -33
- package/tests/AllowedOrdi.test.ts +0 -47
- package/tests/AllowedOxbt.test.ts +0 -47
- package/tests/AllowedProjectlCollection.test.ts +0 -51
- package/tests/AllowedProtocolCollection.test.ts +0 -44
- package/tests/AllowedStamps.test.ts +0 -73
- package/tests/DarkfarmsMetadata.test.ts +0 -10
- package/tests/EmblemVaultSdk.test.ts +0 -124
- package/tests/fixtures/embels/balance.json +0 -10
- package/tests/fixtures/ethscriptions/balance-with-native-first.json +0 -69
- package/tests/fixtures/ethscriptions/balance-with-native.json +0 -37
- package/tests/fixtures/ethscriptions/balance.json +0 -64
- /package/{tests → test}/fixtures/bells/balance-with-non-bell-first.json +0 -0
- /package/{tests → test}/fixtures/bells/balance-with-non-bell.json +0 -0
- /package/{tests → test}/fixtures/bells/balance.json +0 -0
- /package/{tests → test}/fixtures/bitcoin-degods/balance-with-non-degods-first.json +0 -0
- /package/{tests → test}/fixtures/bitcoin-degods/balance-with-non-degods.json +0 -0
- /package/{tests → test}/fixtures/bitcoin-degods/balance.json +0 -0
- /package/{tests → test}/fixtures/bitcoin-ordinals/balance-with-native-first.json +0 -0
- /package/{tests → test}/fixtures/bitcoin-ordinals/balance-with-only-native.json +0 -0
- /package/{tests → test}/fixtures/bitcoin-ordinals/balance.json +0 -0
- /package/{tests → test}/fixtures/counterparty/balance-with-multiple.json +0 -0
- /package/{tests → test}/fixtures/counterparty/balance.json +0 -0
- /package/{tests → test}/fixtures/cursed-ordinals/balance-with-native-first.json +0 -0
- /package/{tests → test}/fixtures/cursed-ordinals/balance-with-native.json +0 -0
- /package/{tests → test}/fixtures/cursed-ordinals/balance.json +0 -0
- /package/{tests → test}/fixtures/dogeparty/balance-with-non-dogeparty-first.json +0 -0
- /package/{tests → test}/fixtures/dogeparty/balance-with-non-dogeparty.json +0 -0
- /package/{tests → test}/fixtures/dogeparty/balance.json +0 -0
- /package/{tests → test}/fixtures/emblem-open/balance.json +0 -0
- /package/{tests → test}/fixtures/hardcoded-nfts/balance-witn-non-hardcoded-first.json +0 -0
- /package/{tests → test}/fixtures/hardcoded-nfts/balance-witn-non-hardcoded.json +0 -0
- /package/{tests → test}/fixtures/hardcoded-nfts/balance.json +0 -0
- /package/{tests → test}/fixtures/megapunks/balance-with-non-megapunk-first.json +0 -0
- /package/{tests → test}/fixtures/megapunks/balance-with-non-megapunk.json +0 -0
- /package/{tests → test}/fixtures/megapunks/balance.json +0 -0
- /package/{tests → test}/fixtures/namecoin/balance-with-native-first.json +0 -0
- /package/{tests → test}/fixtures/namecoin/balance-with-native.json +0 -0
- /package/{tests → test}/fixtures/namecoin/balance.json +0 -0
- /package/{tests → test}/fixtures/ordi/balance-with-native-first.json +0 -0
- /package/{tests → test}/fixtures/ordi/balance-with-native.json +0 -0
- /package/{tests → test}/fixtures/ordi/balance.json +0 -0
- /package/{tests → test}/fixtures/oxbt/balance-with-native-first.json +0 -0
- /package/{tests → test}/fixtures/oxbt/balance-with-native.json +0 -0
- /package/{tests → test}/fixtures/oxbt/balance.json +0 -0
- /package/{tests → test}/fixtures/stamps/balance-with-non-stamps-first.json +0 -0
- /package/{tests → test}/fixtures/stamps/balance-with-non-stamps.json +0 -0
- /package/{tests → test}/fixtures/stamps/balance.json +0 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emblem Vault SDK Signing Tests
|
|
3
|
+
* Tests for blockchain signing operations in the SDK
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { expect } = require('chai');
|
|
7
|
+
const sinon = require('sinon');
|
|
8
|
+
const { EmblemVaultSDK } = require('../../dist/index.js');
|
|
9
|
+
const { Web3ProviderAdapter } = require('../../dist/providers.js');
|
|
10
|
+
|
|
11
|
+
// Test constants
|
|
12
|
+
const API_KEY = 'test-api-key';
|
|
13
|
+
const TEST_TOKEN_ID = '12345';
|
|
14
|
+
const TEST_ACCOUNT = '0x1234567890123456789012345678901234567890';
|
|
15
|
+
const TEST_SIGNATURE = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';
|
|
16
|
+
const TEST_BLOCK_NUMBER = '12345678';
|
|
17
|
+
const TEST_CHAIN_ID = '1'; // Ethereum mainnet
|
|
18
|
+
|
|
19
|
+
describe('Signing Operations', () => {
|
|
20
|
+
let sdk;
|
|
21
|
+
let mockWeb3;
|
|
22
|
+
let mockEthProvider;
|
|
23
|
+
let getConnectedEthAccountStub;
|
|
24
|
+
let getBlockNumberStub;
|
|
25
|
+
let getChainIdStub;
|
|
26
|
+
let expectedMessage;
|
|
27
|
+
let fetchDataStub;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
// Create stubs for web3 methods
|
|
31
|
+
getBlockNumberStub = sinon.stub().returns({
|
|
32
|
+
toString: () => TEST_BLOCK_NUMBER
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Create a chainId that has a toString method to match the implementation
|
|
36
|
+
getChainIdStub = sinon.stub().returns({
|
|
37
|
+
toString: () => TEST_CHAIN_ID
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Create a mock Web3 instance with stubbed methods
|
|
41
|
+
mockWeb3 = {
|
|
42
|
+
eth: {
|
|
43
|
+
getAccounts: sinon.stub().resolves([TEST_ACCOUNT]),
|
|
44
|
+
getBlockNumber: getBlockNumberStub,
|
|
45
|
+
getChainId: getChainIdStub,
|
|
46
|
+
personal: {
|
|
47
|
+
sign: sinon.stub().resolves(TEST_SIGNATURE),
|
|
48
|
+
recover: sinon.stub().resolves(TEST_ACCOUNT)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Create a mock Ethereum provider
|
|
54
|
+
mockEthProvider = {
|
|
55
|
+
eth: mockWeb3.eth,
|
|
56
|
+
isConnected: sinon.stub().resolves(true)
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Create a new SDK instance
|
|
60
|
+
sdk = new EmblemVaultSDK(API_KEY);
|
|
61
|
+
|
|
62
|
+
// Register the mock provider directly
|
|
63
|
+
sdk.registerProvider('ethereum', mockEthProvider);
|
|
64
|
+
|
|
65
|
+
// Stub getOrDetectProvider to return our registered provider
|
|
66
|
+
sinon.stub(sdk, 'getOrDetectProvider').resolves(mockEthProvider);
|
|
67
|
+
|
|
68
|
+
// Stub the getConnectedEthAccount method to return our test account
|
|
69
|
+
getConnectedEthAccountStub = sinon.stub(sdk, 'getConnectedEthAccount').resolves(TEST_ACCOUNT);
|
|
70
|
+
|
|
71
|
+
// Create a stub for fetchData in the global scope
|
|
72
|
+
// We need to ensure this is properly defined and accessible
|
|
73
|
+
global.fetchData = sinon.stub();
|
|
74
|
+
fetchDataStub = global.fetchData;
|
|
75
|
+
|
|
76
|
+
// Set up the expected message format
|
|
77
|
+
expectedMessage = `Curated Minting: ${TEST_TOKEN_ID} \n\nat Block# ${TEST_BLOCK_NUMBER}`;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
afterEach(() => {
|
|
81
|
+
sinon.restore();
|
|
82
|
+
// Clean up global stubs
|
|
83
|
+
if (global.fetchData && global.fetchData.restore) {
|
|
84
|
+
global.fetchData.restore();
|
|
85
|
+
}
|
|
86
|
+
delete global.fetchData;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('requestV3LocalMintSignature', () => {
|
|
90
|
+
it('should request a signature for minting using the provider', async () => {
|
|
91
|
+
// Call the method
|
|
92
|
+
const result = await sdk.requestV3LocalMintSignature(TEST_TOKEN_ID);
|
|
93
|
+
|
|
94
|
+
// Verify the provider was requested
|
|
95
|
+
expect(sdk.getOrDetectProvider.called).to.be.true;
|
|
96
|
+
|
|
97
|
+
// Verify the block number was retrieved
|
|
98
|
+
expect(getBlockNumberStub.called).to.be.true;
|
|
99
|
+
|
|
100
|
+
// Verify the account was retrieved
|
|
101
|
+
expect(getConnectedEthAccountStub.called).to.be.true;
|
|
102
|
+
|
|
103
|
+
// Verify the signature was requested with the correct parameters
|
|
104
|
+
expect(mockEthProvider.eth.personal.sign.called).to.be.true;
|
|
105
|
+
|
|
106
|
+
// Check that the message contains the token ID
|
|
107
|
+
const signMessage = mockEthProvider.eth.personal.sign.firstCall.args[0];
|
|
108
|
+
expect(signMessage).to.include(TEST_TOKEN_ID);
|
|
109
|
+
|
|
110
|
+
// Check that the message contains "Block#" - we don't check the exact number
|
|
111
|
+
// since the implementation might format it differently
|
|
112
|
+
expect(signMessage).to.include('Block#');
|
|
113
|
+
|
|
114
|
+
expect(mockEthProvider.eth.personal.sign.firstCall.args[1]).to.equal(TEST_ACCOUNT);
|
|
115
|
+
|
|
116
|
+
// Verify the result has the correct structure
|
|
117
|
+
expect(result).to.be.an('object');
|
|
118
|
+
expect(result).to.have.property('message').that.includes(TEST_TOKEN_ID);
|
|
119
|
+
expect(result).to.have.property('message').that.includes('Block#');
|
|
120
|
+
expect(result).to.have.property('signature', TEST_SIGNATURE);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should use the override function when provided', async () => {
|
|
124
|
+
// Create a mock override function
|
|
125
|
+
const overrideSignature = '0x0verr1deS1gnature';
|
|
126
|
+
const overrideFunc = sinon.stub().resolves(overrideSignature);
|
|
127
|
+
|
|
128
|
+
// Call the method with the override function
|
|
129
|
+
const result = await sdk.requestV3LocalMintSignature(TEST_TOKEN_ID, null, overrideFunc);
|
|
130
|
+
|
|
131
|
+
// Verify the override function was called with the correct parameters
|
|
132
|
+
expect(overrideFunc.called).to.be.true;
|
|
133
|
+
|
|
134
|
+
// Check that the override function was called with message and account directly
|
|
135
|
+
const messageArg = overrideFunc.firstCall.args[0];
|
|
136
|
+
expect(messageArg).to.include(TEST_TOKEN_ID);
|
|
137
|
+
expect(messageArg).to.include('Block#');
|
|
138
|
+
expect(overrideFunc.firstCall.args[1]).to.equal(TEST_ACCOUNT);
|
|
139
|
+
|
|
140
|
+
// Verify the provider's sign method was NOT called
|
|
141
|
+
expect(mockEthProvider.eth.personal.sign.called).to.be.false;
|
|
142
|
+
|
|
143
|
+
// Verify the result structure
|
|
144
|
+
expect(result).to.be.an('object');
|
|
145
|
+
expect(result).to.have.property('message').that.includes(TEST_TOKEN_ID);
|
|
146
|
+
expect(result).to.have.property('message').that.includes('Block#');
|
|
147
|
+
expect(result).to.have.property('signature', overrideSignature);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should call the callback function when provided', async () => {
|
|
151
|
+
// Create a mock callback function
|
|
152
|
+
const callback = sinon.spy();
|
|
153
|
+
|
|
154
|
+
// Call the method with the callback
|
|
155
|
+
await sdk.requestV3LocalMintSignature(TEST_TOKEN_ID, callback);
|
|
156
|
+
|
|
157
|
+
// Verify the callback was called with the correct parameters
|
|
158
|
+
expect(callback.calledTwice).to.be.true;
|
|
159
|
+
expect(callback.firstCall.args[0]).to.equal('requesting Owner Mint Signature');
|
|
160
|
+
expect(callback.secondCall.args[0]).to.equal('signature');
|
|
161
|
+
expect(callback.secondCall.args[1]).to.equal(TEST_SIGNATURE);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should throw an error when no connected account is found', async () => {
|
|
165
|
+
// Make getConnectedEthAccount return null to simulate no connected account
|
|
166
|
+
getConnectedEthAccountStub.resolves(null);
|
|
167
|
+
|
|
168
|
+
// Call the method and expect it to throw
|
|
169
|
+
try {
|
|
170
|
+
await sdk.requestV3LocalMintSignature(TEST_TOKEN_ID);
|
|
171
|
+
// If we get here, the test failed
|
|
172
|
+
expect.fail('Should have thrown an error');
|
|
173
|
+
} catch (error) {
|
|
174
|
+
// Verify the error message
|
|
175
|
+
expect(error.message).to.equal('No connected wallet found');
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('requestV3RemoteMintSignature', () => {
|
|
181
|
+
// Mock responses for tests
|
|
182
|
+
const mockSuccessResponse = {
|
|
183
|
+
success: true,
|
|
184
|
+
_price: 1000000,
|
|
185
|
+
_signature: '0xremoteSignature'
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const mockErrorResponse = {
|
|
189
|
+
error: 'Invalid signature'
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
let originalMethod;
|
|
193
|
+
|
|
194
|
+
beforeEach(() => {
|
|
195
|
+
// Save the original method
|
|
196
|
+
originalMethod = sdk.requestV3RemoteMintSignature;
|
|
197
|
+
|
|
198
|
+
// Create a stub for the method that we can control
|
|
199
|
+
sdk.requestV3RemoteMintSignature = sinon.stub();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
afterEach(() => {
|
|
203
|
+
// Restore the original method
|
|
204
|
+
sdk.requestV3RemoteMintSignature = originalMethod;
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should request a remote signature using the provider', async () => {
|
|
208
|
+
// Configure the stub to return a success response
|
|
209
|
+
sdk.requestV3RemoteMintSignature.resolves(mockSuccessResponse);
|
|
210
|
+
|
|
211
|
+
// Call the method
|
|
212
|
+
const result = await sdk.requestV3RemoteMintSignature(TEST_TOKEN_ID, TEST_SIGNATURE);
|
|
213
|
+
|
|
214
|
+
// Verify the method was called with the correct parameters
|
|
215
|
+
expect(sdk.requestV3RemoteMintSignature.calledWith(TEST_TOKEN_ID, TEST_SIGNATURE)).to.be.true;
|
|
216
|
+
|
|
217
|
+
// Verify the result
|
|
218
|
+
expect(result).to.deep.equal(mockSuccessResponse);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('should use the override function when provided', async () => {
|
|
222
|
+
// Create a mock override function
|
|
223
|
+
const overrideFunc = sinon.stub().resolves(mockSuccessResponse);
|
|
224
|
+
|
|
225
|
+
// Configure the stub to use the override function
|
|
226
|
+
sdk.requestV3RemoteMintSignature.callsFake(async (tokenId, signature, callback, override) => {
|
|
227
|
+
if (override) {
|
|
228
|
+
return await override();
|
|
229
|
+
}
|
|
230
|
+
return mockSuccessResponse;
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Call the method with the override function
|
|
234
|
+
const result = await sdk.requestV3RemoteMintSignature(TEST_TOKEN_ID, TEST_SIGNATURE, null, overrideFunc);
|
|
235
|
+
|
|
236
|
+
// Verify the method was called with the correct parameters
|
|
237
|
+
expect(sdk.requestV3RemoteMintSignature.calledWith(TEST_TOKEN_ID, TEST_SIGNATURE, null, overrideFunc)).to.be.true;
|
|
238
|
+
|
|
239
|
+
// Verify the result
|
|
240
|
+
expect(result).to.deep.equal(mockSuccessResponse);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should throw an error when the remote response contains an error', async () => {
|
|
244
|
+
// Configure the stub to throw an error
|
|
245
|
+
sdk.requestV3RemoteMintSignature.rejects(new Error('Invalid signature'));
|
|
246
|
+
|
|
247
|
+
// Call the method and expect it to throw an error
|
|
248
|
+
let errorThrown = false;
|
|
249
|
+
try {
|
|
250
|
+
await sdk.requestV3RemoteMintSignature(TEST_TOKEN_ID, TEST_SIGNATURE);
|
|
251
|
+
} catch (error) {
|
|
252
|
+
errorThrown = true;
|
|
253
|
+
expect(error.message).to.equal('Invalid signature');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Verify an error was thrown
|
|
257
|
+
expect(errorThrown).to.be.true;
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should call the callback function when provided', async () => {
|
|
261
|
+
// Create a mock callback function
|
|
262
|
+
const callback = sinon.spy();
|
|
263
|
+
|
|
264
|
+
// Configure the stub to call the callback and return a success response
|
|
265
|
+
sdk.requestV3RemoteMintSignature.callsFake(async (tokenId, signature, cb) => {
|
|
266
|
+
if (cb) {
|
|
267
|
+
cb('requesting Remote Mint signature');
|
|
268
|
+
cb('remote Mint signature', mockSuccessResponse);
|
|
269
|
+
}
|
|
270
|
+
return mockSuccessResponse;
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Call the method with the callback
|
|
274
|
+
const result = await sdk.requestV3RemoteMintSignature(TEST_TOKEN_ID, TEST_SIGNATURE, callback);
|
|
275
|
+
|
|
276
|
+
// Verify the callback was called
|
|
277
|
+
expect(callback.called).to.be.true;
|
|
278
|
+
expect(callback.calledWith('requesting Remote Mint signature')).to.be.true;
|
|
279
|
+
expect(callback.calledWith('remote Mint signature', mockSuccessResponse)).to.be.true;
|
|
280
|
+
|
|
281
|
+
// Verify the result
|
|
282
|
+
expect(result).to.deep.equal(mockSuccessResponse);
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
describe('recoverSignerFromMessage', () => {
|
|
287
|
+
it('should recover the signer address from a message and signature', async () => {
|
|
288
|
+
// Call the method
|
|
289
|
+
const result = await sdk.recoverSignerFromMessage(expectedMessage, TEST_SIGNATURE);
|
|
290
|
+
|
|
291
|
+
// Verify the provider's recover method was called with the correct parameters
|
|
292
|
+
expect(mockEthProvider.eth.personal.recover.called).to.be.true;
|
|
293
|
+
expect(mockEthProvider.eth.personal.recover.firstCall.args[0]).to.equal(expectedMessage);
|
|
294
|
+
expect(mockEthProvider.eth.personal.recover.firstCall.args[1]).to.equal(TEST_SIGNATURE);
|
|
295
|
+
|
|
296
|
+
// Verify the result
|
|
297
|
+
expect(result).to.equal(TEST_ACCOUNT);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should use the override function when provided', async () => {
|
|
301
|
+
// Create a mock override function
|
|
302
|
+
const overrideFunc = sinon.stub().resolves(TEST_ACCOUNT);
|
|
303
|
+
|
|
304
|
+
// Call the method with the override function
|
|
305
|
+
const result = await sdk.recoverSignerFromMessage(expectedMessage, TEST_SIGNATURE, overrideFunc);
|
|
306
|
+
|
|
307
|
+
// Verify the override function was called with the correct parameters
|
|
308
|
+
expect(overrideFunc.called).to.be.true;
|
|
309
|
+
expect(overrideFunc.firstCall.args[0]).to.equal(expectedMessage);
|
|
310
|
+
expect(overrideFunc.firstCall.args[1]).to.equal(TEST_SIGNATURE);
|
|
311
|
+
|
|
312
|
+
// Verify the provider's recover method was NOT called
|
|
313
|
+
expect(mockEthProvider.eth.personal.recover.called).to.be.false;
|
|
314
|
+
|
|
315
|
+
// Verify the result
|
|
316
|
+
expect(result).to.equal(TEST_ACCOUNT);
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Additional signing tests can be added here as more methods are implemented
|
|
321
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const { expect } = require('chai');
|
|
2
|
+
const { EmblemVaultSDK } = require('../../dist/index');
|
|
3
|
+
|
|
4
|
+
// API key for testing
|
|
5
|
+
const API_KEY = 'test-api-key';
|
|
6
|
+
const AI_API_KEY = 'test-ai-api-key';
|
|
7
|
+
const AI_URL = 'https://api.emblemvault.ai';
|
|
8
|
+
|
|
9
|
+
describe('Emblem Vault AI', () => {
|
|
10
|
+
describe('Vault AI Operations', () => {
|
|
11
|
+
let sdk;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
// Create a new SDK instance with custom AI URL and API key for testing
|
|
15
|
+
sdk = new EmblemVaultSDK(API_KEY, undefined, undefined, undefined, AI_URL, AI_API_KEY);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should use the correct URL and API key when getting vault info', async () => {
|
|
19
|
+
// Track the URL, API key, and headers that were passed to the override function
|
|
20
|
+
let capturedUrl;
|
|
21
|
+
let capturedApiKey;
|
|
22
|
+
let capturedMethod;
|
|
23
|
+
let capturedBody;
|
|
24
|
+
let capturedHeaders;
|
|
25
|
+
|
|
26
|
+
// Create an override function that captures all parameters
|
|
27
|
+
const overrideFunc = (url, apiKey, method, body, headers) => {
|
|
28
|
+
capturedUrl = url;
|
|
29
|
+
capturedApiKey = apiKey;
|
|
30
|
+
capturedMethod = method;
|
|
31
|
+
capturedBody = body;
|
|
32
|
+
capturedHeaders = headers;
|
|
33
|
+
|
|
34
|
+
// Return mock data
|
|
35
|
+
return Promise.resolve({
|
|
36
|
+
success: true,
|
|
37
|
+
vaultId: 'mock-vault-id',
|
|
38
|
+
owner: 'mock-owner-address',
|
|
39
|
+
createdAt: new Date().toISOString()
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Call the method with the override function
|
|
44
|
+
const result = await sdk.vaultInfoFromApiKey(undefined, true, overrideFunc);
|
|
45
|
+
|
|
46
|
+
// Verify all parameters were correct
|
|
47
|
+
expect(capturedUrl).to.equal(`${AI_URL}/vault/info-complete`);
|
|
48
|
+
expect(capturedApiKey).to.equal(AI_API_KEY);
|
|
49
|
+
expect(capturedMethod).to.equal('POST');
|
|
50
|
+
expect(capturedBody).to.equal(null);
|
|
51
|
+
|
|
52
|
+
// Verify the mock data was returned
|
|
53
|
+
expect(result).to.be.an('object');
|
|
54
|
+
expect(result.success).to.be.true;
|
|
55
|
+
expect(result.vaultId).to.equal('mock-vault-id');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should prioritize the provided API key over the SDK instance API key', async () => {
|
|
59
|
+
const providedApiKey = 'provided-api-key';
|
|
60
|
+
let capturedUrl;
|
|
61
|
+
let capturedApiKey;
|
|
62
|
+
let capturedHeaders;
|
|
63
|
+
|
|
64
|
+
// Create an override function that captures the URL, API key and headers
|
|
65
|
+
const overrideFunc = (url, apiKey, method, body, headers) => {
|
|
66
|
+
capturedUrl = url;
|
|
67
|
+
capturedApiKey = apiKey;
|
|
68
|
+
capturedHeaders = headers;
|
|
69
|
+
return Promise.resolve({ success: true });
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Call the method with a provided API key and the override function
|
|
73
|
+
await sdk.vaultInfoFromApiKey(providedApiKey, true, overrideFunc);
|
|
74
|
+
|
|
75
|
+
// Verify the provided API key was used instead of the SDK instance API key
|
|
76
|
+
expect(capturedUrl).to.equal(`${AI_URL}/vault/info-complete`);
|
|
77
|
+
expect(capturedApiKey).to.equal(providedApiKey);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should handle the case when no API key is provided', async () => {
|
|
81
|
+
// Create an SDK instance without an AI API key
|
|
82
|
+
const sdkWithoutAiKey = new EmblemVaultSDK(API_KEY, undefined, undefined, undefined, AI_URL);
|
|
83
|
+
|
|
84
|
+
let capturedUrl;
|
|
85
|
+
let capturedApiKey;
|
|
86
|
+
let capturedMethod;
|
|
87
|
+
let capturedBody;
|
|
88
|
+
let capturedHeaders;
|
|
89
|
+
|
|
90
|
+
// Create an override function that captures all parameters
|
|
91
|
+
const overrideFunc = (url, apiKey, method, body, headers) => {
|
|
92
|
+
capturedUrl = url;
|
|
93
|
+
capturedApiKey = apiKey;
|
|
94
|
+
capturedMethod = method;
|
|
95
|
+
capturedBody = body;
|
|
96
|
+
capturedHeaders = headers;
|
|
97
|
+
return Promise.resolve({ success: true });
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Call the method without providing an API key
|
|
101
|
+
await sdkWithoutAiKey.vaultInfoFromApiKey(undefined, true, overrideFunc);
|
|
102
|
+
|
|
103
|
+
// Verify all parameters were correct
|
|
104
|
+
expect(capturedUrl).to.equal(`${AI_URL}/vault/info-complete`);
|
|
105
|
+
expect(capturedApiKey).to.equal('');
|
|
106
|
+
expect(capturedMethod).to.equal('POST');
|
|
107
|
+
expect(capturedBody).to.equal(null);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should use sdk ai api key when no api key is provided', async () => {
|
|
111
|
+
// Create an SDK instance without an AI API key
|
|
112
|
+
const sdkWithoutAiKey = new EmblemVaultSDK(API_KEY, undefined, undefined, undefined, AI_URL, AI_API_KEY);
|
|
113
|
+
|
|
114
|
+
let capturedUrl;
|
|
115
|
+
let capturedApiKey;
|
|
116
|
+
let capturedMethod;
|
|
117
|
+
let capturedBody;
|
|
118
|
+
let capturedHeaders;
|
|
119
|
+
|
|
120
|
+
// Create an override function that captures all parameters
|
|
121
|
+
const overrideFunc = (url, apiKey, method, body, headers) => {
|
|
122
|
+
capturedUrl = url;
|
|
123
|
+
capturedApiKey = apiKey;
|
|
124
|
+
capturedMethod = method;
|
|
125
|
+
capturedBody = body;
|
|
126
|
+
capturedHeaders = headers;
|
|
127
|
+
return Promise.resolve({ success: true });
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Call the method without providing an API key
|
|
131
|
+
await sdkWithoutAiKey.vaultInfoFromApiKey(undefined, true, overrideFunc);
|
|
132
|
+
|
|
133
|
+
// Verify all parameters were correct
|
|
134
|
+
expect(capturedUrl).to.equal(`${AI_URL}/vault/info-complete`);
|
|
135
|
+
expect(capturedApiKey).to.equal(AI_API_KEY);
|
|
136
|
+
expect(capturedMethod).to.equal('POST');
|
|
137
|
+
expect(capturedBody).to.equal(null);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|