Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

Commit 8db407f

Browse files
Fixes did ion long form resolution (#435)
* Fixed resolution problems. * Add canonical ID when applying patch changes to a did doc * ptr
1 parent 30892e2 commit 8db407f

File tree

6 files changed

+137
-26
lines changed

6 files changed

+137
-26
lines changed

credential/integrity/signature_test.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package integrity
22

33
import (
44
"context"
5+
"net/http"
56
"testing"
67
"time"
78

89
"github.com/TBD54566975/ssi-sdk/credential"
10+
"github.com/TBD54566975/ssi-sdk/did/ion"
911
"github.com/goccy/go-json"
1012

1113
"github.com/TBD54566975/ssi-sdk/crypto"
@@ -79,8 +81,8 @@ func TestVerifyCredentialSignature(t *testing.T) {
7981
resolver, err := resolution.NewResolver([]resolution.Resolver{key.Resolver{}}...)
8082
assert.NoError(tt, err)
8183

82-
credential := getTestCredential()
83-
credBytes, err := json.Marshal(credential)
84+
testCred := getTestCredential()
85+
credBytes, err := json.Marshal(testCred)
8486
assert.NoError(tt, err)
8587
_, err = VerifyCredentialSignature(context.Background(), credBytes, resolver)
8688
assert.Error(tt, err)
@@ -224,6 +226,15 @@ func TestVerifyJWTCredential(t *testing.T) {
224226
assert.NoError(tt, err)
225227
assert.True(tt, verified)
226228
})
229+
230+
t.Run("valid credential with long form ion did", func(t *testing.T) {
231+
resolver, err := ion.NewIONResolver(http.DefaultClient, "https://ion.example.com")
232+
assert.NoError(t, err)
233+
const jwtCred = `eyJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6aW9uOkVpQmp6ZUtpVzdXU3lqRUdtai1Jc3NlZDVoTWVmbU0yX0h3eWJLN2RTckRfWEE6ZXlKa1pXeDBZU0k2ZXlKd1lYUmphR1Z6SWpwYmV5SmhZM1JwYjI0aU9pSnlaWEJzWVdObElpd2laRzlqZFcxbGJuUWlPbnNpY0hWaWJHbGpTMlY1Y3lJNlczc2lhV1FpT2lKemFXZGZNalF6T0dOaU1tUWlMQ0p3ZFdKc2FXTkxaWGxLZDJzaU9uc2lZM0oySWpvaWMyVmpjREkxTm1zeElpd2lhM1I1SWpvaVJVTWlMQ0o0SWpvaVZFUkdVbWxPVTNkR2NHMTBjVFZYWDNrNVJIaG9NRGgwWlVKNlNGWkxWemxEYW5kMVJIUjVObGxKVlNJc0lua2lPaUpmVjNjMWNEUldjRVJvYkRGMmFVNUplVXRmTTFkVmJqVmlkSEowT0dWcmVqWm5OMHBIV1VaVVVVWTRJbjBzSW5CMWNuQnZjMlZ6SWpwYkltRjFkR2hsYm5ScFkyRjBhVzl1SWl3aVlYTnpaWEowYVc5dVRXVjBhRzlrSWwwc0luUjVjR1VpT2lKRlkyUnpZVk5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGtpZlYwc0luTmxjblpwWTJWeklqcGJleUpwWkNJNklteHBibXRsWkdSdmJXRnBibk1pTENKelpYSjJhV05sUlc1a2NHOXBiblFpT25zaWIzSnBaMmx1Y3lJNld5Sm9kSFJ3Y3pvdkwyeHBibXRsWkdsdUxtTnZiUzhpWFgwc0luUjVjR1VpT2lKTWFXNXJaV1JFYjIxaGFXNXpJbjBzZXlKcFpDSTZJbWgxWWlJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnBibk4wWVc1alpYTWlPbHNpYUhSMGNITTZMeTlpWlhSaExtaDFZaTV0YzJsa1pXNTBhWFI1TG1OdmJTOTJNUzR3THpVNE9XUTFNMkkxTFdSbFpqVXROREl6TlMxaU5qUXlMVGhsTVdNME1XVTRZbU5oTVNKZGZTd2lkSGx3WlNJNklrbGtaVzUwYVhSNVNIVmlJbjFkZlgxZExDSjFjR1JoZEdWRGIyMXRhWFJ0Wlc1MElqb2lSV2xCYlRVdGFFNXRWbmhTVVZkT1ptMTNRelpXTVRaaE4wYzNTbTVyVHpNNGFVZFVVRlkyTjNGNFEzTkRkeUo5TENKemRXWm1hWGhFWVhSaElqcDdJbVJsYkhSaFNHRnphQ0k2SWtWcFFqRlBRa2huYWt0amFrcGtMVkZRZWkxUllXWlFibGRCZW1SdWNtaDVXVkIyVUVsZlZuSnpUbTVYZDBFaUxDSnlaV052ZG1WeWVVTnZiVzFwZEcxbGJuUWlPaUpGYVVNMk5uTllTR1ZHTWtseWRuaElTM3BDY1dWRVRHd3pWRU5TUzJwVlpFSnNkbVJmYmtaS01GcDNZVFJuSW4xOSNzaWdfMjQzOGNiMmQifQ.eyJzdWIiOiJkaWQ6aW9uOkVpQmp6ZUtpVzdXU3lqRUdtai1Jc3NlZDVoTWVmbU0yX0h3eWJLN2RTckRfWEE6ZXlKa1pXeDBZU0k2ZXlKd1lYUmphR1Z6SWpwYmV5SmhZM1JwYjI0aU9pSnlaWEJzWVdObElpd2laRzlqZFcxbGJuUWlPbnNpY0hWaWJHbGpTMlY1Y3lJNlczc2lhV1FpT2lKemFXZGZNalF6T0dOaU1tUWlMQ0p3ZFdKc2FXTkxaWGxLZDJzaU9uc2lZM0oySWpvaWMyVmpjREkxTm1zeElpd2lhM1I1SWpvaVJVTWlMQ0o0SWpvaVZFUkdVbWxPVTNkR2NHMTBjVFZYWDNrNVJIaG9NRGgwWlVKNlNGWkxWemxEYW5kMVJIUjVObGxKVlNJc0lua2lPaUpmVjNjMWNEUldjRVJvYkRGMmFVNUplVXRmTTFkVmJqVmlkSEowT0dWcmVqWm5OMHBIV1VaVVVVWTRJbjBzSW5CMWNuQnZjMlZ6SWpwYkltRjFkR2hsYm5ScFkyRjBhVzl1SWl3aVlYTnpaWEowYVc5dVRXVjBhRzlrSWwwc0luUjVjR1VpT2lKRlkyUnpZVk5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGtpZlYwc0luTmxjblpwWTJWeklqcGJleUpwWkNJNklteHBibXRsWkdSdmJXRnBibk1pTENKelpYSjJhV05sUlc1a2NHOXBiblFpT25zaWIzSnBaMmx1Y3lJNld5Sm9kSFJ3Y3pvdkwyeHBibXRsWkdsdUxtTnZiUzhpWFgwc0luUjVjR1VpT2lKTWFXNXJaV1JFYjIxaGFXNXpJbjBzZXlKcFpDSTZJbWgxWWlJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnBibk4wWVc1alpYTWlPbHNpYUhSMGNITTZMeTlpWlhSaExtaDFZaTV0YzJsa1pXNTBhWFI1TG1OdmJTOTJNUzR3THpVNE9XUTFNMkkxTFdSbFpqVXROREl6TlMxaU5qUXlMVGhsTVdNME1XVTRZbU5oTVNKZGZTd2lkSGx3WlNJNklrbGtaVzUwYVhSNVNIVmlJbjFkZlgxZExDSjFjR1JoZEdWRGIyMXRhWFJ0Wlc1MElqb2lSV2xCYlRVdGFFNXRWbmhTVVZkT1ptMTNRelpXTVRaaE4wYzNTbTVyVHpNNGFVZFVVRlkyTjNGNFEzTkRkeUo5TENKemRXWm1hWGhFWVhSaElqcDdJbVJsYkhSaFNHRnphQ0k2SWtWcFFqRlBRa2huYWt0amFrcGtMVkZRZWkxUllXWlFibGRCZW1SdWNtaDVXVkIyVUVsZlZuSnpUbTVYZDBFaUxDSnlaV052ZG1WeWVVTnZiVzFwZEcxbGJuUWlPaUpGYVVNMk5uTllTR1ZHTWtseWRuaElTM3BDY1dWRVRHd3pWRU5TUzJwVlpFSnNkbVJmYmtaS01GcDNZVFJuSW4xOSIsImlzcyI6ImRpZDppb246RWlCanplS2lXN1dTeWpFR21qLUlzc2VkNWhNZWZtTTJfSHd5Yks3ZFNyRF9YQTpleUprWld4MFlTSTZleUp3WVhSamFHVnpJanBiZXlKaFkzUnBiMjRpT2lKeVpYQnNZV05sSWl3aVpHOWpkVzFsYm5RaU9uc2ljSFZpYkdsalMyVjVjeUk2VzNzaWFXUWlPaUp6YVdkZk1qUXpPR05pTW1RaUxDSndkV0pzYVdOTFpYbEtkMnNpT25zaVkzSjJJam9pYzJWamNESTFObXN4SWl3aWEzUjVJam9pUlVNaUxDSjRJam9pVkVSR1VtbE9VM2RHY0cxMGNUVlhYM2s1Ukhob01EaDBaVUo2U0ZaTFZ6bERhbmQxUkhSNU5sbEpWU0lzSW5raU9pSmZWM2MxY0RSV2NFUm9iREYyYVU1SmVVdGZNMWRWYmpWaWRISjBPR1ZyZWpabk4wcEhXVVpVVVVZNEluMHNJbkIxY25CdmMyVnpJanBiSW1GMWRHaGxiblJwWTJGMGFXOXVJaXdpWVhOelpYSjBhVzl1VFdWMGFHOWtJbDBzSW5SNWNHVWlPaUpGWTJSellWTmxZM0F5TlRack1WWmxjbWxtYVdOaGRHbHZia3RsZVRJd01Ua2lmVjBzSW5ObGNuWnBZMlZ6SWpwYmV5SnBaQ0k2SW14cGJtdGxaR1J2YldGcGJuTWlMQ0p6WlhKMmFXTmxSVzVrY0c5cGJuUWlPbnNpYjNKcFoybHVjeUk2V3lKb2RIUndjem92TDJ4cGJtdGxaR2x1TG1OdmJTOGlYWDBzSW5SNWNHVWlPaUpNYVc1clpXUkViMjFoYVc1ekluMHNleUpwWkNJNkltaDFZaUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKcGJuTjBZVzVqWlhNaU9sc2lhSFIwY0hNNkx5OWlaWFJoTG1oMVlpNXRjMmxrWlc1MGFYUjVMbU52YlM5Mk1TNHdMelU0T1dRMU0ySTFMV1JsWmpVdE5ESXpOUzFpTmpReUxUaGxNV00wTVdVNFltTmhNU0pkZlN3aWRIbHdaU0k2SWtsa1pXNTBhWFI1U0hWaUluMWRmWDFkTENKMWNHUmhkR1ZEYjIxdGFYUnRaVzUwSWpvaVJXbEJiVFV0YUU1dFZuaFNVVmRPWm0xM1F6WldNVFpoTjBjM1NtNXJUek00YVVkVVVGWTJOM0Y0UTNORGR5SjlMQ0p6ZFdabWFYaEVZWFJoSWpwN0ltUmxiSFJoU0dGemFDSTZJa1ZwUWpGUFFraG5ha3RqYWtwa0xWRlFlaTFSWVdaUWJsZEJlbVJ1Y21oNVdWQjJVRWxmVm5KelRtNVhkMEVpTENKeVpXTnZkbVZ5ZVVOdmJXMXBkRzFsYm5RaU9pSkZhVU0yTm5OWVNHVkdNa2x5ZG5oSVMzcENjV1ZFVEd3elZFTlNTMnBWWkVKc2RtUmZia1pLTUZwM1lUUm5JbjE5IiwibmJmIjoxNjQ5Mjg2NzM3LCJleHAiOjI0MzgyMDUxMzcsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9pZGVudGl0eS5mb3VuZGF0aW9uLy53ZWxsLWtub3duL2NvbnRleHRzL2RpZC1jb25maWd1cmF0aW9uLXYwLjAuanNvbmxkIl0sImlzc3VlciI6ImRpZDppb246RWlCanplS2lXN1dTeWpFR21qLUlzc2VkNWhNZWZtTTJfSHd5Yks3ZFNyRF9YQTpleUprWld4MFlTSTZleUp3WVhSamFHVnpJanBiZXlKaFkzUnBiMjRpT2lKeVpYQnNZV05sSWl3aVpHOWpkVzFsYm5RaU9uc2ljSFZpYkdsalMyVjVjeUk2VzNzaWFXUWlPaUp6YVdkZk1qUXpPR05pTW1RaUxDSndkV0pzYVdOTFpYbEtkMnNpT25zaVkzSjJJam9pYzJWamNESTFObXN4SWl3aWEzUjVJam9pUlVNaUxDSjRJam9pVkVSR1VtbE9VM2RHY0cxMGNUVlhYM2s1Ukhob01EaDBaVUo2U0ZaTFZ6bERhbmQxUkhSNU5sbEpWU0lzSW5raU9pSmZWM2MxY0RSV2NFUm9iREYyYVU1SmVVdGZNMWRWYmpWaWRISjBPR1ZyZWpabk4wcEhXVVpVVVVZNEluMHNJbkIxY25CdmMyVnpJanBiSW1GMWRHaGxiblJwWTJGMGFXOXVJaXdpWVhOelpYSjBhVzl1VFdWMGFHOWtJbDBzSW5SNWNHVWlPaUpGWTJSellWTmxZM0F5TlRack1WWmxjbWxtYVdOaGRHbHZia3RsZVRJd01Ua2lmVjBzSW5ObGNuWnBZMlZ6SWpwYmV5SnBaQ0k2SW14cGJtdGxaR1J2YldGcGJuTWlMQ0p6WlhKMmFXTmxSVzVrY0c5cGJuUWlPbnNpYjNKcFoybHVjeUk2V3lKb2RIUndjem92TDJ4cGJtdGxaR2x1TG1OdmJTOGlYWDBzSW5SNWNHVWlPaUpNYVc1clpXUkViMjFoYVc1ekluMHNleUpwWkNJNkltaDFZaUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKcGJuTjBZVzVqWlhNaU9sc2lhSFIwY0hNNkx5OWlaWFJoTG1oMVlpNXRjMmxrWlc1MGFYUjVMbU52YlM5Mk1TNHdMelU0T1dRMU0ySTFMV1JsWmpVdE5ESXpOUzFpTmpReUxUaGxNV00wTVdVNFltTmhNU0pkZlN3aWRIbHdaU0k2SWtsa1pXNTBhWFI1U0hWaUluMWRmWDFkTENKMWNHUmhkR1ZEYjIxdGFYUnRaVzUwSWpvaVJXbEJiVFV0YUU1dFZuaFNVVmRPWm0xM1F6WldNVFpoTjBjM1NtNXJUek00YVVkVVVGWTJOM0Y0UTNORGR5SjlMQ0p6ZFdabWFYaEVZWFJoSWpwN0ltUmxiSFJoU0dGemFDSTZJa1ZwUWpGUFFraG5ha3RqYWtwa0xWRlFlaTFSWVdaUWJsZEJlbVJ1Y21oNVdWQjJVRWxmVm5KelRtNVhkMEVpTENKeVpXTnZkbVZ5ZVVOdmJXMXBkRzFsYm5RaU9pSkZhVU0yTm5OWVNHVkdNa2x5ZG5oSVMzcENjV1ZFVEd3elZFTlNTMnBWWkVKc2RtUmZia1pLTUZwM1lUUm5JbjE5IiwiaXNzdWFuY2VEYXRlIjoiMjAyMi0wNC0wNlQyMzoxMjoxNy44MzVaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDQ3LTA0LTA2VDIzOjEyOjE3LjgzNVoiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRG9tYWluTGlua2FnZUNyZWRlbnRpYWwiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6aW9uOkVpQmp6ZUtpVzdXU3lqRUdtai1Jc3NlZDVoTWVmbU0yX0h3eWJLN2RTckRfWEE6ZXlKa1pXeDBZU0k2ZXlKd1lYUmphR1Z6SWpwYmV5SmhZM1JwYjI0aU9pSnlaWEJzWVdObElpd2laRzlqZFcxbGJuUWlPbnNpY0hWaWJHbGpTMlY1Y3lJNlczc2lhV1FpT2lKemFXZGZNalF6T0dOaU1tUWlMQ0p3ZFdKc2FXTkxaWGxLZDJzaU9uc2lZM0oySWpvaWMyVmpjREkxTm1zeElpd2lhM1I1SWpvaVJVTWlMQ0o0SWpvaVZFUkdVbWxPVTNkR2NHMTBjVFZYWDNrNVJIaG9NRGgwWlVKNlNGWkxWemxEYW5kMVJIUjVObGxKVlNJc0lua2lPaUpmVjNjMWNEUldjRVJvYkRGMmFVNUplVXRmTTFkVmJqVmlkSEowT0dWcmVqWm5OMHBIV1VaVVVVWTRJbjBzSW5CMWNuQnZjMlZ6SWpwYkltRjFkR2hsYm5ScFkyRjBhVzl1SWl3aVlYTnpaWEowYVc5dVRXVjBhRzlrSWwwc0luUjVjR1VpT2lKRlkyUnpZVk5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGtpZlYwc0luTmxjblpwWTJWeklqcGJleUpwWkNJNklteHBibXRsWkdSdmJXRnBibk1pTENKelpYSjJhV05sUlc1a2NHOXBiblFpT25zaWIzSnBaMmx1Y3lJNld5Sm9kSFJ3Y3pvdkwyeHBibXRsWkdsdUxtTnZiUzhpWFgwc0luUjVjR1VpT2lKTWFXNXJaV1JFYjIxaGFXNXpJbjBzZXlKcFpDSTZJbWgxWWlJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnBibk4wWVc1alpYTWlPbHNpYUhSMGNITTZMeTlpWlhSaExtaDFZaTV0YzJsa1pXNTBhWFI1TG1OdmJTOTJNUzR3THpVNE9XUTFNMkkxTFdSbFpqVXROREl6TlMxaU5qUXlMVGhsTVdNME1XVTRZbU5oTVNKZGZTd2lkSGx3WlNJNklrbGtaVzUwYVhSNVNIVmlJbjFkZlgxZExDSjFjR1JoZEdWRGIyMXRhWFJ0Wlc1MElqb2lSV2xCYlRVdGFFNXRWbmhTVVZkT1ptMTNRelpXTVRaaE4wYzNTbTVyVHpNNGFVZFVVRlkyTjNGNFEzTkRkeUo5TENKemRXWm1hWGhFWVhSaElqcDdJbVJsYkhSaFNHRnphQ0k2SWtWcFFqRlBRa2huYWt0amFrcGtMVkZRZWkxUllXWlFibGRCZW1SdWNtaDVXVkIyVUVsZlZuSnpUbTVYZDBFaUxDSnlaV052ZG1WeWVVTnZiVzFwZEcxbGJuUWlPaUpGYVVNMk5uTllTR1ZHTWtseWRuaElTM3BDY1dWRVRHd3pWRU5TUzJwVlpFSnNkbVJmYmtaS01GcDNZVFJuSW4xOSIsIm9yaWdpbiI6Imh0dHBzOi8vd3d3LmxpbmtlZGluLmNvbS8ifX19.oTFcVvKmYU1Mxh9Q4V5UNikddYANLjw-m3530PNDhFYmR1Dm8DOcjdU-p2rJ6vSZnUKatXV5VJLJxj1aJyuhlw`
234+
verified, err := VerifyJWTCredential(context.Background(), jwtCred, resolver)
235+
assert.NoError(t, err)
236+
assert.True(t, verified)
237+
})
227238
}
228239

229240
func getTestJWTCredential(t *testing.T, signer jwx.Signer) string {

did/ion/did.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,24 @@ func PatchesToDIDDocument(shortFormDID, longFormDID string, patches []Patch) (*d
117117
return nil, errors.New("short form DID is required")
118118
}
119119
doc := did.Document{
120-
Context: []string{"https://www.w3.org/ns/did/v1"},
121-
ID: shortFormDID,
122-
AlsoKnownAs: longFormDID,
120+
Context: []any{"https://www.w3.org/ns/did/v1", map[string]any{
121+
"@base": longFormDID,
122+
}},
123+
ID: longFormDID,
123124
}
124125
for _, patch := range patches {
125126
switch patch.GetAction() {
126127
case AddServices:
127128
addServicePatch := patch.(AddServicesAction)
128-
doc.Services = append(doc.Services, addServicePatch.Services...)
129+
for _, s := range addServicePatch.Services {
130+
s := s
131+
s.ID = canonicalID(s.ID)
132+
doc.Services = append(doc.Services, s)
133+
}
129134
case RemoveServices:
130135
removeServicePatch := patch.(RemoveServicesAction)
131136
for _, id := range removeServicePatch.IDs {
137+
id := canonicalID(id)
132138
for i, service := range doc.Services {
133139
if service.ID == id {
134140
doc.Services = append(doc.Services[:i], doc.Services[i+1:]...)
@@ -180,14 +186,17 @@ func replaceActionPatch(doc did.Document, patch ReplaceAction) (*did.Document, e
180186
}
181187
doc = *gotDoc
182188
for _, service := range patch.Document.Services {
183-
doc.Services = append(doc.Services, service)
189+
s := service
190+
s.ID = canonicalID(s.ID)
191+
doc.Services = append(doc.Services, s)
184192
}
185193
return &doc, nil
186194
}
187195

188196
func addPublicKeysPatch(doc did.Document, patch AddPublicKeysAction) (*did.Document, error) {
189197
for _, key := range patch.PublicKeys {
190198
currKey := key
199+
currKey.ID = canonicalID(currKey.ID)
191200
doc.VerificationMethod = append(doc.VerificationMethod, did.VerificationMethod{
192201
ID: currKey.ID,
193202
Type: cryptosuite.LDKeyType(currKey.Type),
@@ -214,8 +223,16 @@ func addPublicKeysPatch(doc did.Document, patch AddPublicKeysAction) (*did.Docum
214223
return &doc, nil
215224
}
216225

226+
func canonicalID(id string) string {
227+
if strings.Contains(id, "#") {
228+
return id
229+
}
230+
return "#" + id
231+
}
232+
217233
func removePublicKeysPatch(doc did.Document, patch RemovePublicKeysAction) (*did.Document, error) {
218234
for _, id := range patch.IDs {
235+
id := canonicalID(id)
219236
removed := false
220237
for i, key := range doc.VerificationMethod {
221238
if key.ID != id {

did/ion/did_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,77 @@
11
package ion
22

33
import (
4+
"context"
5+
"net/http"
46
"testing"
57

68
"github.com/TBD54566975/ssi-sdk/crypto/jwx"
79
"github.com/TBD54566975/ssi-sdk/did"
10+
"github.com/goccy/go-json"
811
"github.com/stretchr/testify/assert"
912
)
1013

14+
// Test vector from https://identity.foundation/sidetree/spec/#long-form-response, adjusted by replacing s/sidetree/ion/
15+
func TestResolveLongFormDID(t *testing.T) {
16+
longFormDID := `did:ion:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJwdWJsaWNLZXlNb2RlbDFJZCIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJ0WFNLQl9ydWJYUzdzQ2pYcXVwVkpFelRjVzNNc2ptRXZxMVlwWG45NlpnIiwieSI6ImRPaWNYcWJqRnhvR0otSzAtR0oxa0hZSnFpY19EX09NdVV3a1E3T2w2bmsifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJrZXlBZ3JlZW1lbnQiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoic2VydmljZTFJZCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly93d3cuc2VydmljZTEuY29tIiwidHlwZSI6InNlcnZpY2UxVHlwZSJ9XX19XSwidXBkYXRlQ29tbWl0bWVudCI6IkVpREtJa3dxTzY5SVBHM3BPbEhrZGI4Nm5ZdDBhTnhTSFp1MnItYmhFem5qZEEifSwic3VmZml4RGF0YSI6eyJkZWx0YUhhc2giOiJFaUNmRFdSbllsY0Q5RUdBM2RfNVoxQUh1LWlZcU1iSjluZmlxZHo1UzhWRGJnIiwicmVjb3ZlcnlDb21taXRtZW50IjoiRWlCZk9aZE10VTZPQnc4UGs4NzlRdFotMkotOUZiYmpTWnlvYUFfYnFENHpoQSJ9fQ`
17+
resolver, err := NewIONResolver(http.DefaultClient, "https://example.com")
18+
assert.NoError(t, err)
19+
20+
resolutionResult, err := resolver.Resolve(context.Background(), longFormDID)
21+
assert.NoError(t, err)
22+
23+
jsonResolutionResult, err := json.Marshal(resolutionResult)
24+
assert.NoError(t, err)
25+
26+
expectedResolutionResultJSON := `{
27+
"@context": "https://w3id.org/did-resolution/v1",
28+
"didDocument": {
29+
"id": "did:ion:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJwdWJsaWNLZXlNb2RlbDFJZCIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJ0WFNLQl9ydWJYUzdzQ2pYcXVwVkpFelRjVzNNc2ptRXZxMVlwWG45NlpnIiwieSI6ImRPaWNYcWJqRnhvR0otSzAtR0oxa0hZSnFpY19EX09NdVV3a1E3T2w2bmsifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJrZXlBZ3JlZW1lbnQiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoic2VydmljZTFJZCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly93d3cuc2VydmljZTEuY29tIiwidHlwZSI6InNlcnZpY2UxVHlwZSJ9XX19XSwidXBkYXRlQ29tbWl0bWVudCI6IkVpREtJa3dxTzY5SVBHM3BPbEhrZGI4Nm5ZdDBhTnhTSFp1MnItYmhFem5qZEEifSwic3VmZml4RGF0YSI6eyJkZWx0YUhhc2giOiJFaUNmRFdSbllsY0Q5RUdBM2RfNVoxQUh1LWlZcU1iSjluZmlxZHo1UzhWRGJnIiwicmVjb3ZlcnlDb21taXRtZW50IjoiRWlCZk9aZE10VTZPQnc4UGs4NzlRdFotMkotOUZiYmpTWnlvYUFfYnFENHpoQSJ9fQ",
30+
"@context": [
31+
"https://www.w3.org/ns/did/v1",
32+
{
33+
"@base": "did:ion:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJwdWJsaWNLZXlNb2RlbDFJZCIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJ0WFNLQl9ydWJYUzdzQ2pYcXVwVkpFelRjVzNNc2ptRXZxMVlwWG45NlpnIiwieSI6ImRPaWNYcWJqRnhvR0otSzAtR0oxa0hZSnFpY19EX09NdVV3a1E3T2w2bmsifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJrZXlBZ3JlZW1lbnQiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoic2VydmljZTFJZCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly93d3cuc2VydmljZTEuY29tIiwidHlwZSI6InNlcnZpY2UxVHlwZSJ9XX19XSwidXBkYXRlQ29tbWl0bWVudCI6IkVpREtJa3dxTzY5SVBHM3BPbEhrZGI4Nm5ZdDBhTnhTSFp1MnItYmhFem5qZEEifSwic3VmZml4RGF0YSI6eyJkZWx0YUhhc2giOiJFaUNmRFdSbllsY0Q5RUdBM2RfNVoxQUh1LWlZcU1iSjluZmlxZHo1UzhWRGJnIiwicmVjb3ZlcnlDb21taXRtZW50IjoiRWlCZk9aZE10VTZPQnc4UGs4NzlRdFotMkotOUZiYmpTWnlvYUFfYnFENHpoQSJ9fQ"
34+
}
35+
],
36+
"service": [
37+
{
38+
"id": "#service1Id",
39+
"type": "service1Type",
40+
"serviceEndpoint": "http://www.service1.com"
41+
}
42+
],
43+
"verificationMethod": [
44+
{
45+
"id": "#publicKeyModel1Id",
46+
"controller": "did:ion:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJwdWJsaWNLZXlNb2RlbDFJZCIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJ0WFNLQl9ydWJYUzdzQ2pYcXVwVkpFelRjVzNNc2ptRXZxMVlwWG45NlpnIiwieSI6ImRPaWNYcWJqRnhvR0otSzAtR0oxa0hZSnFpY19EX09NdVV3a1E3T2w2bmsifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJrZXlBZ3JlZW1lbnQiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoic2VydmljZTFJZCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly93d3cuc2VydmljZTEuY29tIiwidHlwZSI6InNlcnZpY2UxVHlwZSJ9XX19XSwidXBkYXRlQ29tbWl0bWVudCI6IkVpREtJa3dxTzY5SVBHM3BPbEhrZGI4Nm5ZdDBhTnhTSFp1MnItYmhFem5qZEEifSwic3VmZml4RGF0YSI6eyJkZWx0YUhhc2giOiJFaUNmRFdSbllsY0Q5RUdBM2RfNVoxQUh1LWlZcU1iSjluZmlxZHo1UzhWRGJnIiwicmVjb3ZlcnlDb21taXRtZW50IjoiRWlCZk9aZE10VTZPQnc4UGs4NzlRdFotMkotOUZiYmpTWnlvYUFfYnFENHpoQSJ9fQ",
47+
"type": "EcdsaSecp256k1VerificationKey2019",
48+
"publicKeyJwk": {
49+
"crv": "secp256k1",
50+
"kty": "EC",
51+
"x": "tXSKB_rubXS7sCjXqupVJEzTcW3MsjmEvq1YpXn96Zg",
52+
"y": "dOicXqbjFxoGJ-K0-GJ1kHYJqic_D_OMuUwkQ7Ol6nk"
53+
}
54+
}
55+
],
56+
"authentication": [
57+
"#publicKeyModel1Id"
58+
],
59+
"keyAgreement": [
60+
"#publicKeyModel1Id"
61+
]
62+
},
63+
"didDocumentMetadata": {
64+
"equivalentId": ["did:ion:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg"],
65+
"method": {
66+
"published": false,
67+
"recoveryCommitment": "EiBfOZdMtU6OBw8Pk879QtZ-2J-9FbbjSZyoaA_bqD4zhA",
68+
"updateCommitment": "EiDKIkwqO69IPG3pOlHkdb86nYt0aNxSHZu2r-bhEznjdA"
69+
}
70+
}
71+
}`
72+
assert.JSONEq(t, expectedResolutionResultJSON, string(jsonResolutionResult))
73+
}
74+
1175
// https://github.com/decentralized-identity/ion-sdk/blob/main/tests/IonDid.spec.ts#L18
1276
func TestCreateLongFormDID(t *testing.T) {
1377
var recoveryKey jwx.PublicKeyJWK

did/ion/operations_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ func TestResolver(t *testing.T) {
125125
result, err := resolver.Resolve(context.Background(), longFormDID, nil)
126126
assert.NoError(ttt, err)
127127
assert.NotEmpty(ttt, result)
128-
assert.Equal(ttt, "did:ion:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg", result.Document.ID)
129-
assert.Equal(ttt, longFormDID, result.Document.AlsoKnownAs)
128+
assert.Equal(ttt, longFormDID, result.Document.ID)
130129
})
131130
})
132131

did/ion/resolver.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,16 @@ func (i Resolver) Resolve(ctx context.Context, id string, _ ...resolution.Option
6464
if err != nil {
6565
return nil, errors.Wrap(err, "reconstructing document from long form DID")
6666
}
67-
return &resolution.Result{Document: *didDoc}, nil
67+
return &resolution.Result{
68+
Context: "https://w3id.org/did-resolution/v1",
69+
Document: *didDoc,
70+
DocumentMetadata: &resolution.DocumentMetadata{
71+
EquivalentID: []string{shortFormDID},
72+
Method: resolution.Method{
73+
Published: false,
74+
RecoveryCommitment: initialState.SuffixData.RecoveryCommitment,
75+
UpdateCommitment: initialState.Delta.UpdateCommitment},
76+
}}, nil
6877
}
6978

7079
if i.baseURL.String() == "" {
@@ -79,7 +88,9 @@ func (i Resolver) Resolve(ctx context.Context, id string, _ ...resolution.Option
7988
return nil, errors.Wrapf(err, "resolving, with URL: %s", i.baseURL.String())
8089
}
8190

82-
defer resp.Body.Close()
91+
defer func() {
92+
_ = resp.Body.Close()
93+
}()
8394
body, err := io.ReadAll(resp.Body)
8495
if err != nil {
8596
return nil, errors.Wrapf(err, "resolving, with response %+v", resp)
@@ -114,7 +125,9 @@ func (i Resolver) Anchor(ctx context.Context, op AnchorOperation) (*resolution.R
114125
return nil, errors.Wrapf(err, "posting anchor operation %+v", op)
115126
}
116127

117-
defer resp.Body.Close()
128+
defer func() {
129+
_ = resp.Body.Close()
130+
}()
118131
body, err := io.ReadAll(resp.Body)
119132
if err != nil {
120133
return nil, errors.Wrapf(err, "could not resolve with response %+v", resp)

0 commit comments

Comments
 (0)